Hello,

Drupal 7 is creating a canonical tag using /blah rather than domain/blah.

I want to either 1) fix the issue, or 2) disable altogether so I can enable the 'global redirect' module and do it properly.

If I enable the global re-direct module at the moment, I get 2 canonical links, one pointing to /blah and the other pointing to domain/blah, which isn't good!

Thanks,
Neil

CommentFileSizeAuthor
#6 seo-canonical-fail.gif10.51 KBGraeme Blackwood
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

seftonn’s picture

Assigned: Unassigned » seftonn
Status: Active » Closed (fixed)

Yeahhhhh!!!

Fixed it. Probably not the best, but it works and SEOMoz now shows my pages as 'A' grade.

In modules/node.module, removed:

// Set the node path as the canonical URL to prevent duplicate content.
drupal_add_html_head_link(array('rel' => 'canonical', 'href' => url($uri['path'], $uri['options'])), TRUE);

Then switched on canonical links in configuration/global redirects

This removed the incorrect canonical link of /page and replaced with domain/page.

Pancho’s picture

Component: other » node.module
Assigned: seftonn » Unassigned
Category: support » bug
Priority: Major » Normal
Status: Closed (fixed) » Active

If the canonical tag is wrong, this is a bug not just a support request. And even if you fixed it on your site, from the project's POV it's not fixed until a fix was committed to git.

Damien Tournoud’s picture

Status: Active » Closed (works as designed)

1. There is nothing wrong with relative canonical links
2. Those links can be modified by hook_html_head_alter().

I am lost as where there is a bug here.

Pancho’s picture

Project: Drupal core » Global Redirect
Version: 7.x-dev » 7.x-1.x-dev
Component: node.module » Code
Status: Closed (works as designed) » Active

@Damien: This was just a technical status change. I just noticed that the submitter incorrectly closed the issue. Don't want to infer that the submitter's point of view is right.

Having two canonical links, as stated in the initial post, might be a problem though. In this case this is a valid issue in the wrong queue and belongs to Global Redirect's queue. Reopening it there.

clicchick’s picture

I'd like to offer an alternative solution to editing core files like node.module.

I had a similar problem with Drupal using the relative path for the canonical link so that on the mobile version of my site, it would use "http://m.domain.com/path" rather than "http://domain.com/path". Also for some reason Drupal does not insert a canonical link on the front page, or on panel pages. And as previously mentioned, the Global Redirect module does not remove Drupal's default canonical link before adding its own, equally uneditable link.

Thankfully, I was saved from hacking the core (shudder) or writing my own module by the Metatags module. It gives you a great deal of control over not only traditional metatags, but also canonical links and it makes use of the Open Graph protocol. Woohoo :)

Graeme Blackwood’s picture

FileSize
10.51 KB

Just to pick up on this because we have been running into the same issue and are in the process of resolving, Google advises that canonical urls are absolute if possible: http://www.google.com/support/webmasters/bin/answer.py?answer=139394

Clearly SEO Doctor for Firefox also believes this is important, because they seem to flag the SEO status as a big fail unless the canonical url is an absolute path.

Damien Tournoud’s picture

This is the quote from Google:

Can the link be relative or absolute?

rel="canonical" can be used with relative or absolute links, but we recommend using absolute links to minimize potential confusion or difficulties. If your document specifies a base link, any relative links will be relative to that base link.

They just mean "we recommend absolute if you don't know what you are doing". We do. There is nothing wrong with our relative links. SEO Doctor for Firefox needs fixing.

Graeme Blackwood’s picture

That may be generally true, but I guess it is dependent on other processes like proper 301s being set up to redirect between www. and root etc, whereas allowing the setting of an absolute path for canonical would give that extra guarantee and would be a nice option.

I have contacted SEO Doctor to get their opinion, as if this is a bug, it's going to be causing a fair bit of concern among Drupal users.

memoo’s picture

To avoid double canonicals I disabled them in GlobalRedirect settings, and config them in Metatags settings.

Question: is there a difference in the generated canonicals? If so, what is the prefered module to config them? In GlobalRedirect or Metatags?

marcoka’s picture

indigoblue’s picture

Relative Canonical hit me hard with incorrect subdomains getting associated with my content. I fixed the problem in hook_html_head_alter.

function hook_html_head_alter(&$head_elements){ 
     // remove meta generator
      unset($head_elements['system_meta_generator']);
      
       foreach ($head_elements as $key => $element) {      
           if (isset($element['#attributes']['rel'])){
                 switch($element['#attributes']['rel']){
                   // remove shortlink
                    case 'shortlink':
                        unset($head_elements[$key]);
                        break;
                    
                    // full url for canonical    
                    case 'canonical':                      
                        $head_elements[$key]['#attributes']['href'] = $GLOBALS['base_url'].$element['#attributes']['href'];                       
                        break;
                 }              
           }
      }
      // debug
      //print("<pre>");print_r(array_keys($head_elements));print("</pre>"); exit();     
}

I was forced to loop through the elements because some weirdness meant I could not access the element directly. Hope this helps someone.

tudormajic’s picture

A rehash of the above code - works for me. Shout if there is anything wrong you can see here.

function hook_html_head_alter(&$head_elements) {
  global $base_url;
  // Get our current uri.
  $uri = drupal_get_path_alias();

  // We try to match it by forming the right key with the info we have.
  $key = 'drupal_add_html_head_link:canonical:</' . $uri . '>;';

  // Check that it is set, then we re-set it to the correct full url.
  if (isset($head_elements[$key])) {
    // Alter our head_element.
    $head_elements[$key]['#attributes']['href'] = $base_url . '/' .$uri;
  }
} 
sokrplare’s picture

Status: Active » Closed (works as designed)

@tudormajic - your approach in comment 12 (#1104828-12: Canonical tag is wrong) worked beautifully for me! Thanks!

Closing this per Damien's comment above - Drupal architecture decision, not an official "bug" in this case. For those of us who need absolute URLs tudormajic's workaround is great.

phponwebsites’s picture

Is any chance to change canonical url using templeate_preprocess_page()?

e5sego’s picture

If you use multiple languages with language negitiation by path prefix, you have to implement it slightly different:

function hook_html_head_alter(&$head_elements) {
  global $base_url;
  // Get our current uri.
  $uri = url(drupal_get_path_alias());

  // We try to match it by forming the right key with the info we have.
  $key = 'drupal_add_html_head_link:canonical:<' . $uri . '>;';

  // Check that it is set, then we re-set it to the correct full url.
  if (isset($head_elements[$key])) {
    // Alter our head_element.
    $head_elements[$key]['#attributes']['href'] = $base_url . $uri;
  }
}