Plugins You can find out about all the publicly available Grails plugins.

Canonical Tagging Plugin for SEO

  • Tags: /
  • Latest: 0.1
  • Last Updated: 22 February 2010
  • Grails version: 1.2.1 > *
  • Authors: null
0 vote
compile "org.grails.plugins:canonical:0.1"




grails install-plugin canonical


For Search Engine Optimization, it's preferable to align on a single URL for a given page, rather than enabling multiple URLs to resolve to the same content. Under Grails, it's very common to have multiple equivalent URLs. One way to avoid negative impacts due to 'duplicate content' is to add 'canonical' link tags to each page. See the Google Blog for more details:

Show Canonical

This plugin makes it easy to add 'canonical' link tags to each page in a Grails application. After installing the plugin, the following tag can be added to the <head> section of a layout (or wherever head metadata is managed):

<canonical:show />

This will map the current controller, action and paramters back to a 'canonical' URL, taking UrlMappings into consideration. For requests without a controller and action, the actual request URI is assumed to be the desired canonical (this can be disabled). It orders the query parameters, so that pages with the same parameters displayed in a different order display the same tag. It also uses the absolute URL, to address differences that may arise when two different domain names resolve to the same application pages.

This is all that may be required, but the plugin enables some other refinements.

CAUTION: This plugin generates absolute URLs for the canonical tags. Confirm that your grails.serverURL is set properly, such that absolute URLs are being properly constructed.

Exclude Params

In some cases, query parameters are material to the page content, such as an ID parameter. In other cases, the qeury parameter may be required for operations, but is not material to the page content and should be 'ignored' by search engines. In the latter case, these parameters can be excluded from the 'canonical' URLs. The exclusion statement can be applied to all requests by, for example, including it in a global layout. Or, it can be called in a controller or template to apply to a smaller set of requests. To exclude parameters use the following in a layout or template:

<canonical:exclude params="['session', 'source']" />

View Mappings

For view mappings, there is no controller and action involved. Therefore=, reverse resolution of the 'canonical' URL is not possible. In these cases, the URI can be set directly (see below), the URL can be resolved based on the current request (see below), or, a parameter can be added to the mapping which will be used as the base URI. The query String is rebuilt (and properly escaped) from the request, and parameter exclusions are applied. For a mapping in URLMappings.groovy, the feature can be used in this fashion:

"/index"(view:"/index", canonical:"/")

Resolve from Request

If there is no action/controller pair, and no canonical paramter set from URLMappings.groovy, the plugin will try to determine the path using the current request. The path will be built from the HttpServletRequest, the parameters will be built from the current parameter list, and exlcusions applied. The query parameters are then URL-escaped and attached to the path

This 'best guess' may work well in some systems, and abysmally in others. It can be fully disabled by setting:

plugins.canonical.disableResolveFromRequest = true

If turned off, the direct URI set method can still be used to apply canoncial URLs to requests of this type.


Finally, in some cases it may be preferable to override automatuc resolution of the canonical URL with a specific URI. In this case, use the following in the page template (or the equivalent from a controller):

<canonical:set uri="/some/other/place" />
Note that this is a true override: no query string building, parameter exclusions or URL escaping is applied: the URI is used exactly as provided.


Here are some examples of typically equivalent URLs, and how they map to a single canonical URL:

Given a controller called 'example' and an action called 'simple', and the common mappping:

    constraints {
        // apply constraints here

The following URIs:

would resolve to:
<link rel="canonical" href=""/>

Due to parameter ordering, the following URIs:

would both resolve to:
<link rel="canonical" href=""/>

Given a mapping like:

    controller: 'example', action: 'mapped'

The following URIs:

would all resolve to:
<link rel="canonical" href=""/>

For an exclusion list containing 'session' and 'source', the following URIs:

would both resolve to:
<link rel="canonical" href=""/>

Note that if you are externally rewriting URLs outside of UrlMappings, using a tool such as mod_rewrite, this plugin may not produce the desired result: the plugin is unaware of those rewrites.