Starting a new project in Grails might lead to the need to support different languages. This can be done through a default ?lang=locale supported natively by Grails, but if you would like to provide a SEO friendly approach, then you might need to tweak your solution.
First of all, Google has provided a set of recommendation on how to support Multi-regional and multilingual sites. When it comes to URLs, they mention that best practices might include using different geo-domain for each language, using subdomains or subdirectories.

Google Recommendation

URL structures
Consider using a URL structure that makes it easy to geotarget parts of your site to different regions. The following table outlines your options:

URL structure Example Pros Cons
Country-specific example.al
  • Clear geotargeting
  • Server location irrelevant
  • Easy separation of sites
  • Expensive (can have limited availability)
  • Requires more infrastructure
  • Strict ccTLD requirements (sometimes)
Subdomains with gTLDS de.example.com
  • Easy to set up
  • Can use Webmaster Tools geotargeting
  • Allows different server locations
  • Easy separation of sites
  • Users might not recognize geotargeting from the URL alone (is “de” the language or country?)
Subdirectories with gTLDs example.com/de/
  • Easy to set up
  • Can use Webmaster Tools geotargeting
  • Low maintenance (same host)
  • Users might not recognize geotargeting from the URL alone
  • Single server location
  • Separation of sites harder
URL parameters site.com?loc=de
  • Not recommended.
  • URL-based segmentation difficult
  • Users might not recognize geotargeting from the URL alone
  • Geotargeting in Webmaster Tools is not possible

URL Mapping in Grails

Grails has a very neat way of mapping resources to URLs through the URL Mapping.

While the default URL Mapping is:

1
2
3
4
5
 /$controller/$action?/$id?(.$format)?"{
    constraints {
      // apply constraints here
    }
}

Adding support for directories is as simple as adding a $lang parameter

1
2
3
4
5
  /$lang/$controller/$action?/$id?(.$format)?"{
    constraints {
      // apply constraints here
    }
 }

Writing /de/controllername/action will automatically have support for the new language.

The challenge is in defining a default language where the /controllername/action can map without the need of the $lang-parameter.

Posted by xpo6

Software developer in the realm of AI, NLP and black magic.