SEO schema

Simple SEO friendly titles in Java

Sometimes, for SEO purposes, we need to put a string into a URL, like an article title for example.

Let’s say we have an article with the title The title of a nice & simple post !, what we want is the following valid URL: https://example.com/news/2020/the-title-of-a-nice-and-simple-post.

Summary

  1. Set up the project
  2. Make a title URL friendly
  3. Write tests
  4. Conclusion

Set up the project

We will use:

Here is our Maven pom.xml file:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.blebail.blog.sample</groupId>
    <artifactId>java-url-friendly-title</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>java-url-friendly-title</name>
    <url>https://github.com/baptistelebail/samples/tree/master/java-url-friendly-title</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- Guava -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>28.2-jre</version>
        </dependency>

        <!-- JUnit -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.6.0</version>
            <scope>test</scope>
        </dependency>

        <!-- AssertJ -->
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.15.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
            </plugin>
        </plugins>
    </build>
</project>

Make a title URL friendly

We create the SeoString interface:

public interface SeoString {

    String toUrlFriendlyString();
}

Here we will implement a solution only for the English language, other languages would obviously need adjustements.

What we need is to:

  • remove every special characters except &
  • remove any trailing spaces
  • replace spaces with -
  • replace & with and

We create the EnglishTitle class:

import com.google.common.net.UrlEscapers;

import java.util.Objects;

public class EnglishTitle implements SeoString {

    private final String title;

    public EnglishTitle(String title) {
        this.title = Objects.requireNonNull(title);
    }

    /**
     * Builds a url friendly string out of an original string, by :
     * - removing all non alphanumerical characters except '&'
     * - removing trailing spaces
     * - replacing whitespaces with a dash
     * - replacing & with 'and'
     */
    @Override
    public String toUrlFriendlyString() {
        String urlFriendly = title.toLowerCase()
                        .replaceAll("[^a-zA-Z0-9 &]", "")
                        .trim()
                        .replace(' ', '-')
                        .replace("&", "and");
        
                return UrlEscapers.urlPathSegmentEscaper().escape(urlFriendly);
    }
}

At the end we use Guava’s UrlEscapers.urlPathSegmentEscaper() to make sure our string will be correctly encoded for the final URL. (In reality, it is aldready the case, because we removed any special characters, but it is a good practice to ensure it is always the case).

See What every web developer must know about URL encoding for further informations.

Write tests

Let’s write a few tests to validate the behaviour of EnglishTitle.toUrlFriendlyString().

We create EnglishTitleTest in src/test/java:

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

class EnglishTitleTest {

    @Test
    public void shouldPutEveryCharactersToLowerCase() {
        assertThat(new EnglishTitle("ASimpleTitle").toUrlFriendlyString())
                .isEqualTo("asimpletitle");
    }

    @Test
    public void shouldDeleteSpecialCharacters() {
        assertThat(new EnglishTitle("a!si?m=p'le#tit%l)e+").toUrlFriendlyString())
                .isEqualTo("asimpletitle");
    }

    @Test
    public void shouldReplaceSpaceWithDash() {
        assertThat(new EnglishTitle("a simple title").toUrlFriendlyString())
                .isEqualTo("a-simple-title");
    }

    @Test
    public void shouldReplaceAmpersandWithAnd() {
        assertThat(new EnglishTitle("The title of a nice & simple post !").toUrlFriendlyString())
                .isEqualTo("the-title-of-a-nice-and-simple-post");
    }
}

Summary

Making a string URL friendly is not hard, it provides a clean URL and makes it SEO friendly as well.

(The whole project sources are available here)