Adding a rel=canonical link in Wicket for duplicate content

Google recently introduced a new <link rel=”canonical”> tag to help the search engine identify duplicate content across domains or pages. I’m working on a development project that contains many subdomains under a single domain to present content specific to various geographical areas. Some of the administrative pages under each subdomain contain the same content (such as About Us, Privacy Policy, etc.).

The solution is very simple in Wicket by using a behaviour. Create a new behaviour class as shown below and call it in the constructor of each page with duplicate content.

 * Generates a canonical link to a page on the given metro's domain:
 * e.g.,
 * <link rel="canonical" href=">
public class CanonicalRefBehavior extends Behavior {
	private static final long serialVersionUID = 7164872994138228391L;

	private final String domain;
	private final String path;

	public CanonicalRefBehavior(String domain, String path) {
		this.domain = domain;
		this.path = path;

	public void renderHead(Component component, IHeaderResponse response) {
		final StringBuilder sb = new StringBuilder();
		sb.append("<link rel=\"canonical\" href=\"http://");

To make use of this behaviour, call it as follows in the page’s constructor.

add(new CanonicalRefBehavior(

This example assumes that the path doesn’t change between the page being rendered and its canonical reference. If the path differs, then appropriate changes can be made to the the constructor call above.

One comment

  1. I read your article on configuring wiquery and wanted to add something to it but comments are closed there already, so please forgive me for the crossposting..

    You are talking about overriding validateInit or creating a custom initializer, but I think there is a third, more easy way. At least that’s what I’m using now.

    Make your application class implement the IWiQuerySettings interface and implement the getWiQuerySettings method. The default initializer actually calls that method and uses the returned settings object if available. Only if it’s not available will it create a new WiQuerySettings object itself.

    It’s documented here:

    Maybe this info can help you improve even further on the original article that you wrote, which actually ranks pretty high in Google (at least that’s how I found it).