Make WordPress Core

Opened 8 years ago

Closed 8 years ago

Last modified 3 years ago

#33581 closed enhancement (wontfix)

Use history.replaceState instead of 301 redirects for canonical urls

Reported by: peterwilsoncc's profile peterwilsoncc Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Canonical Keywords: 2nd-opinion has-patch
Focuses: javascript, performance Cc:


Currently redirect_canonical uses a 301 redirect sending a user from an ugly permalink to a pretty one.

Replacing with a JavaScript history.replaceState call will reduce time-to-content and lower the server load. The canonical meta tag will keep the ugly URLs out of the big three search engines.

Canonical URLs and paginated posts.

I'd like some SEO feedback on whether search engines respect the canonical meta tag pointing all pages of a paginated posts to the first page of the post. Google's documentation is that it takes the meta tag as a hint rather than a direction.

Attachments (2)

33581.1.diff (6.0 KB) - added by peterwilsoncc 8 years ago.
33581.2.diff (7.8 KB) - added by peterwilsoncc 8 years ago.

Download all attachments as: .zip

Change History (10)

#1 follow-up: @johnbillion
8 years ago

  • Keywords reporter-feedback added

How would this work with browsers that don't support history state?

#2 in reply to: ↑ 1 @peterwilsoncc
8 years ago

  • Keywords needs-patch added; reporter-feedback removed

Replying to johnbillion:

How would this work with browsers that don't support history state?

These browsers would display the ugly permalink:

According to caniuse, global usage stats for the most popular browsers without support are:

  • IE8: 1.58%
  • IE9: 1.25%
  • Opera mini: 4.62%
  • Android 4: 0.28%
  • Android 4.1: 0.78%

Feature detection is used to prevent JavaScript errors in these browsers.

Experimenting with a plugin, the logic I have used is:

  1. 301 redirect if
    • true == is_404()
    • destination domain differs from the requested domain (history state doesn't work)
    • the visitor hits an old slug, eg smaple-slug has been corrected to sample-slug after publishing (is_404)
    • destination domain has been filtered and changed in any way. No way to predict what is meant to happen.
  2. history.replaceState if
    • !is_404(), taking the redirect out will produce the content
    • destination URL is always the value returned by the redirect function - canonical meta tag may differ.

#3 @johnbillion
8 years ago

  • Keywords 2nd-opinion added

I really like this idea, but I wonder whether it's going to cause problems for things like automated QA tools which crawl sites and ensure that redirects are working as expected.

We'll also need some concrete advice about SEO impact.

#4 @peterwilsoncc
8 years ago

  • Keywords has-patch added; needs-patch removed

I've uploaded a patch, if nothing else it gives SEO advisors something to work with.

The patch is quite conservative about attempting to use history.replaceState - deferring to a 301 redirect if anything could go wrong.


  • $do_redirect is no longer concrete, more of a maybe
  • counting preg_replace hits - is this expensive???
  • $compare_redirect_origin and $compare_original_origin might need better names too, now I think of it.

#5 @peterwilsoncc
8 years ago

Refactored in 33581.2.diff to maintain backward compatibility.

New function maybe_redirect_canonical wraps the call to the old function and avoids API changes.

#6 @peterwilsoncc
8 years ago

For the record, reached out to Yoast in <140:

I wouldn’t be in favor, for the reason you mentioned yourself. [Google's documentation is that it takes the meta tag as a hint rather than a direction.]

My reckons should defer to his expertise :)

#7 @helen
8 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

#8 @peterwilsoncc
8 years ago

Any chance to maybe later this ticket? I think the perf benefit worth considering if the SEO advice changes.

Note: See TracTickets for help on using tickets.