How to Create Grails 3 SEO Friendly URL

by Didin J. on Jan 06, 2017 How to Create Grails 3 SEO Friendly URL

Simple example how to create Grails 3 SEO Friendly URL that is important part of SEO optimizing for website or web application.

Today I will show you how to create Grails 3 SEO friendly URL with a simple and effective way without using any plugin. Yes, of course, today you will not find an SEO plugin for Grails 3. But for Grails 2 or less, there is exists.

As default when we call URL, for example, an article it will show like this.

It was because in UrlMappings.groovy of your Grails 3 application it looks like this for calling a single data.

    constraints {
        // apply constraints here

Let me break this.

  • $controller -> article
  • $sction -> show
  • $id -> 10

$format is optional use if you want return json or xml as format.

Your requirement is making SEO friendly URL, so it must look like this.

Yes, you might think that URL not clean because it's too long. But don't worry at least we have our title in the last of URL, it is SEO friendly. And here's the step for it.

1. Create new Service

In your Grails interactive console type this command.

create-service com.djamware.FriendlyUrl

This will create a file with name FriendlyUrlService.groovy, replace the content with this.

package com.djamware

import grails.transaction.Transactional
import java.util.regex.Pattern

class FriendlyUrlService {

  static transactional = false
   * This method transforms the text passed as an argument to a text without spaces,
   * html entities, accents, dots and extranges characters (only %,a-z,A-Z,0-9, ,_ and - are allowed).
   * Borrowed from Wordpress: file wp-includes/formatting.php, function sanitize_title_with_dashes
  def sanitizeWithDashes(text) {
    if(!text) return ""
    // Preserve escaped octets
    text = text.replaceAll('%([a-fA-F0-9][a-fA-F0-9])','---$1---')
    text = text.replaceAll('%','')
    text = text.replaceAll('---([a-fA-F0-9][a-fA-F0-9])---','%$1')
    // Remove accents
    text = removeAccents(text)
    // To lower case
    text = text.toLowerCase()
    // Kill entities
    text = text.replaceAll('&.+?;','')
    // Dots -> ''
    text = text.replaceAll('\\.','')
    // Remove any character except %a-zA-Z0-9 _-
    text = text.replaceAll('[^%a-zA-Z0-9 _-]', '')
    // Trim
    text = text.trim()
    // Spaces -> dashes
    text = text.replaceAll('\\s+', '-')
    // Dashes -> dash
    text = text.replaceAll('-+', '-')
    // It must end in a letter or digit, otherwise we strip the last char
    if (!text[-1].charAt(0).isLetterOrDigit()) text = text[0..-2]
    return text
   * Converts all accent characters to ASCII characters.
   * If there are no accent characters, then the string given is just returned.
  private def removeAccents(text) {
    java.text.Normalizer.normalize(text, java.text.Normalizer.Form.NFD)
        .replaceAll("\\p{InCombiningDiacriticalMarks}+", "")

This code will return any String to SEO required string, in this case, replace space or unwanted characters to be "-".

2. Create new TagLib

As above step type this command.

create-taglib com.djamware.Seo

This will create SeoTagLib.groovy file, then you fill this file same as this.

package com.djamware

class SeoTagLib {
  static namespace = "seo"

    def friendlyUrlService

    def convStr = { attr, body ->
        out << body() << friendlyUrlService.sanitizeWithDashes(attr.value)

With this TagLib we can use our service in GSP page.

3. Register new URL in UrlMappings

Open your UrlMappings.groovy in your Controllers folder. Add this lines.

name showPost: "/post/$id/$title" {
  controller = "article"
  action = "show"

Notes: don't use first arguments ("/post") same as controller name, otherwise it will not working at all.

If you are using spring security, just register this "post" to your application.groovy for accessibility.

4. Create link for your article

By default your link for opening an article url is like this.

<g:link controller="article" action="show" id="${article?.id}">${article?.title}</g:link>

Just replace with this.

<g:link mapping="post" params="[id:, title: seo.convStr(value:article.title)]">

Then try this configuration.

Congratulation, you have SEO friendly URL right now.