Tutorial on how to create Grails SEO friendly URL

publish on

Having SEO friendly URL is very important for your ranking on Google and other search engines. In this article I’ll explain how to generate and handle SEO URLs.

There are no magic Grails plugin to have nice SEO URLs, because URLs depend on your website structure. You have to design your own URLs.

In this site, I’m using the following pattern to build each blog post URL:

{domain}/blog/{blog_id}/{category_name}/{post_title}

Ex: /blog/2/grails/installing-a-grails-plugin

You’ll notice that it’s quite different from the default URL pattern generated by Grails scaffolding:

{domain}/{controller_name}/{action}/{id}

Ex: /blog/show/2

The first step is to tell Grails to respond to the SEO optimized URL.

To do so, add a new URL pattern in UrlMappings.groovy:

name blog: "/blog/$id/$category?/$title?" {
controller = "blog"
action = "show"
}

Name is optional but will be useful to generate links using Grails Taglib <g:link/>.

Grails will map each variable (name preceded by a $ sign) to a request variable that will be accessible in the specified controller (blog) and action (show). Note that the category and title are optional (variable ending with a '?' sign) that means the following URLs will be captured:

{domain}/blog/1
{domain}/blog/1/cat_name
{domain}/blog/1/cat_name/blog_title

Now that Grails is able to handle SEO URLs, we need to generate those links using Grails Taglib <g:link/>.

The second step is to generate SEO links using the <g:link> tag. To do so, you’ll have to provide each parameter (in our example the Blog id, the category name and blog title) that we defined earlier in URLMappings.

Let’s take 2 simple domain objects:

Class Blog {
	String title
	String content
	static belongsTo = [category:Category]
}

And:

Class Category {
	String name
}

In a GSP, we have loaded a Blog instance and used it to generate a SEO link using Grails g:link:

<g:link  mapping="blog"
 params="[id: blogInstance.id, category: blogInstance.category.name ,title: blogInstance.title]">
  ${blogInstance.title}
</g:link>

The above code will generate a link following the pattern we defined in URLMappings.

{domain}/blog/{blog_id}/{category_name}/{post_title}

First, you need to specify a mapping name (blog) and then you have to specify each parameter of the pattern in params. If you missed one, the URL will still be generated but with all the params at the end of the URL following the ? sign. For example if we don’t add the title param it will look like:

{domain}/blog?id=&category_name=&title=

Not very pretty…

Now we have an URL with some keywords in it but there is still a problem, all special characters and spaces will be URL encoded:

"blog test" will be encoded to "blog%20test", etc...

Not very pretty (again)...

But Grails has a nice plugin http://grails.org/plugin/seofriendly-urls that bundle Wordpress's formatting.php file. You can install the plugin or just copy the service from Github FriendlyUrlService.groovy to your Grails services folder

Create a new Grails service:

Right click on one of your project folder and select new > service:


Then enter the complete (including the package) name of the new service (for example com.inoneo.FriendlyUrlService):


Paste the content of FriendlyUrlService.groovy from Github to your newly created service.

Now we need to use this service to create SEO friendly URLs. They are different options here; we can add a method in the Blog domain class that will return the SEO title using the service. Another solution would be to call the service in the controller and inject a new variable containing the SEO title or even directly in the GSP. In My Grails (and Java) applications, I usually like to keep both Controllers and Domains classes as simple and short as possible by keeping most of the logic into services.

As this service will be useful for all kind of domain object, let's create a Taglib to call it directly in GSPs:

Right click on one of your project folder and select new > TagLib:


Then copy the following code:

class SeoTagLib {

	static namespace = "seo"
	
	def friendlyUrlService
	
	/**
	 * Convert the value using the SEO friendly URL service.
	 *
	 * @attr String value to be converted
	 */
	def convert = { attr, body ->
		out << body() << friendlyUrlService.sanitizeWithDashes(attr.value)
	}
}

Note: For performance consideration, avoid calling transactional services in TagLibs because a transaction to the database will be created each time you call the TagLib. In our case FriendlyUrlService is not transactional:

class FriendlyUrlService {

	static transactional = false
...
}

Finally we can use the Seo TagLib in conjunction with g:link to create an SEO friendly URL:

<g:link  mapping="blog"
 params="[id: blogInstance.id, category: seo.convert(value:blogInstance.category.name) ,title: seo.convert(blogInstance.title)]">
  ${blogInstance.title}
</g:link>

comments powered by Disqus