Skip to content

Instantly share code, notes, and snippets.

@amboutwe
Last active November 21, 2023 17:12
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save amboutwe/2aa7dcc9a38986e11fac68c7306cc091 to your computer and use it in GitHub Desktop.
Save amboutwe/2aa7dcc9a38986e11fac68c7306cc091 to your computer and use it in GitHub Desktop.
Code snippets for the Yoast SEO canonical output
<?php
/********* DO NOT COPY THE PARTS ABOVE THIS LINE *********/
/* Change the canonical link for the shop page
* Credit: Scott Weiss of somethumb.com
* Yoast Doc: https://developer.yoast.com/features/seo-tags/canonical-urls/api/
* Last Tested: Jan 25 2017 using Yoast SEO 6.0 on WordPress 4.9.1
*/
add_filter( 'wpseo_canonical', 'yoast_seo_canonical_change_woocom_shop', 10, 1 );
function yoast_seo_canonical_change_woocom_shop( $canonical ) {
if ( !is_shop() ) {
return $canonical;
}
return get_permalink( woocommerce_get_page_id( 'shop' ) );
}
<?php
/********* DO NOT COPY THE PARTS ABOVE THIS LINE *********/
/* Remove Yoast SEO Canonical From All Pages
* Credit: Yoast Team
* Yoast Doc: https://developer.yoast.com/features/seo-tags/canonical-urls/api/
* Last Tested: Jun 16 2017 using Yoast SEO 4.9 on WordPress 4.8
*/
add_filter( 'wpseo_canonical', '__return_false' );
<?php
/********* DO NOT COPY THE PARTS ABOVE THIS LINE *********/
/* Remove Yoast SEO Canonical From Individual or Multiple Items
* Credit: Yoast Team
* Yoast Doc: https://developer.yoast.com/features/seo-tags/canonical-urls/api/
* Last Tested: Jun 16 2017 using Yoast SEO 4.9 on WordPress 4.8
*********
* DIFFERENT POST TYPES
* Post: Change 123456 to the post ID
* Page: Change is_single to is_page and 123456 to the page ID
* Custom Post Type: Change is_single to is_singular and 123456 to the 'post_type_slug'
Example: is_singular( 'cpt_slug' )
*********
* MULTIPLE ITEMS
* Multiple of the same type can use an array.
Example: is_single( array( 123456, 1234567, 12345678 ) )
* Multiple of different types can repeat the if statement
*/
add_filter( 'wpseo_canonical', 'yoast_remove_canonical_items' );
function yoast_remove_canonical_items( $canonical ) {
if ( is_single ( 123456 ) ) {
return false;
}
/* Use a second if statement here when needed */
return $canonical; /* Do not remove this line */
}
<?php
/********* DO NOT COPY THE PARTS ABOVE THIS LINE *********/
/* Remove Yoast SEO Canonical From Search Pages Only
* Credit: Yoast Team
* Yoast Doc: https://developer.yoast.com/features/seo-tags/canonical-urls/api/
* Last Tested: Jun 16 2017 using Yoast SEO 4.9 on WordPress 4.8
*/
add_filter( 'wpseo_canonical', 'yoast_remove_canonical_search' );
function yoast_remove_canonical_search( $canonical ) {
if( is_search() ) {
return false;
} else {
return $canonical;
}
}
<?php
/********* DO NOT COPY THE PARTS ABOVE THIS LINE *********/
/* Add trailing slash to all Yoast SEO canonicals
* Credit: Unknown
* Yoast Doc: https://developer.yoast.com/features/seo-tags/canonical-urls/api/
* Last Tested: Oct 25 2019 using Yoast SEO 12.3 on WordPress 5.2.4
*/
add_filter( 'wpseo_canonical', 'yoast_seo_canonical_slash_add' );
function yoast_seo_canonical_slash_add( $canonical_url ) {
return trailingslashit( $canonical_url );
}
<?php
/********* DO NOT COPY THE PARTS ABOVE THIS LINE *********/
/* Remove trailing slash from all Yoast SEO canonicals
* Credit: Unknown
* Yoast Doc: https://developer.yoast.com/features/seo-tags/canonical-urls/api/
* Last Tested: Oct 25 2019 using Yoast SEO 12.3 on WordPress 5.2.4
*/
add_filter( 'wpseo_canonical', 'yoast_seo_canonical_slash_remove' );
function yoast_seo_canonical_slash_remove( $canonical_url ) {
return untrailingslashit( $canonical_url );
}
@jgresalfi
Copy link

Thanks for posting these -- is there a way to clear canonicals based on whether or not they're on a standard post? I want to leave them on pages but remove from posts but can't find whether or not there's a "type" that identifies all standard WP posts.

@amboutwe
Copy link
Author

@jgresalfi is_single() without a post id should work for all posts while leaving pages alone.

@sebastianheinz
Copy link

sebastianheinz commented Oct 3, 2017

Is there a way to set the canonical to the current page/language URL for self referencing?

@amboutwe
Copy link
Author

amboutwe commented Oct 4, 2017

@sebastianheinz The default canonical is the permalink for the post/page.

@erichazann
Copy link

I think I have the same question as sebastianheinz. According to best practices for canonicals and hreflang attributes, the canonical should be set to the language/localized url, but Yoast uses the permalink of the page w/o any localization parameters. Is there a code sample to pass through the localization params? Example: www.example.com/article-title/?hl=es The Yoast canonical is www.example.com/article-title/, when I need it to be ww.example.com/article-title/?hl=es. Thanks!

@shamsiaidin
Copy link

hi, 1-what is this codes do with Canonical ?
2- in product page we have to description , one that shown in description tab bottom of product and one is expert description which show front of product picture in single page of product, if we want to use description tab contents for snippet Search Appearance what variable must be use?

@ashki1
Copy link

ashki1 commented Sep 7, 2018

Hello there

I have a site like - https://mysite.com and I see the canonical name to be http://mysite.com . (note the http part here). Now I want it to be changed to https. Can anyone please guide me with that.

As of now this is what it looks like - in the source code

I want to use wpseo_canonical filter in WP and i'm stuck.

Any help is appreciated!

@iparker
Copy link

iparker commented Feb 28, 2019

Hello,

it seems that the woocommerce product detail pages and the woocommerce cart have no canonical output in header. Is this possible?

@ptrickey
Copy link

ptrickey commented Mar 23, 2019

My blog archives page is "https://servicechannel.info/blog"
This is being generated in the source code:
link rel="next" href="https://servicechannel.info/category/blog/page/2/"

I would like to remove the /category/ part of the string, and just have:
link rel="next" href="https://servicechannel.info/blog/page/2/"

There is code in the functions.php which removes /category/ so the links work without it, I just need to figure out how to remove /category/ from the generated tag. Any help would be much appreciated.

@slicecrowd
Copy link

Hello @ptricky,
you can try this structure and to put a point in categoty base
изображение

@michelefalconi
Copy link

Hello there

I have a site like - https://mysite.com and I see the canonical name to be http://mysite.com . (note the http part here). Now I want it to be changed to https. Can anyone please guide me with that.

As of now this is what it looks like - in the source code

I want to use wpseo_canonical filter in WP and i'm stuck.

Any help is appreciated!

Have the same problem here. Anyone may help us?
Thank you!

@Hashmi512
Copy link

I need a little help with my site https://asksubtitle.com/ showing up duplicate meta title and description. I am using Yoast SEO plugin and have no idea how to set up Canonical URL on page 2/3... to avoid duplication. Please guide me through the process.

@amboutwe
Copy link
Author

amboutwe commented Sep 9, 2019

This is not the proper place to request support. Please check out our extensive Knowledge Base or visit the free support forum. If you require further support, upgrading to our premium version provides you with access to our support team.

@campaignupgrade
Copy link

Is the first example wrong? There's no $canonical_url variable in the wpseo plugin.

@amboutwe
Copy link
Author

@campaignupgrade The example is correct. The $canonical_url is a local variable for the custom function.

Bonus: Last tested date has been updated as I verified it worked today. Plus I added another snippet to remove the trailing slash for those that might need to do the opposite. Renamed the snippets to better align with what the code does.

@campaignupgrade
Copy link

Ah I see. If it's not pulling an already-defined varaible like $canonical it's just a local variable and it replaces whatever the output of generate_canonical().

@campaignupgrade
Copy link

campaignupgrade commented Oct 25, 2019

I'm looking for a clean way to replace the base_url of all my non-production sites with my production base_url. Unfortunately it doesn't look like I can override the individual subfunctions involved, so would a pregex_replace( $canonical ) approach be the only option?

I'm short on time and haven't thoroughly tested this, but it's working so far:

/**
* Set canonical URLs on non-production sites to the production URL
* Stops bots from indexing
* @link https://gist.github.com/amboutwe/2aa7dcc9a38986e11fac68c7306cc091
*/

add_filter( 'wpseo_canonical', function( $canonical ) {

  if( 'https://example.com' ==  get_option( 'home' ) ) {
    return $canonical;
  }

  $canonical = preg_replace('#//[^/]*/#U', '//example.com/', trailingslashit( $canonical ) );
  return $canonical;
});

@marouane91
Copy link

I have a page that is generated only in php !

So Is there a way to add a custom canonical or title/description tags for this specific page ?

Any help would be much appreciated ?

@amboutwe
Copy link
Author

amboutwe commented Jan 2, 2020

This is not the proper place to request support. Please check out our extensive Knowledge Base or visit the free support forum. If you require further support, upgrading to our premium version provides you with access to our support team.

@viniciusmiranda22
Copy link

Hi, does anyone knows how can I fix this? Somes slashes BEFORE my canonicals started to appear on all pages like the image below:

Captura-de-Tela-2020-06-21-às-18 02 56

@amboutwe
Copy link
Author

@viniciusmiranda22 As mentioned above, this is not the proper place to request support. Please check out our extensive help section or visit the free support forum. If you require further support, upgrading to our premium version provides you with access to our support team.

@frontend-coder
Copy link

yoast_seo_canonical_change_woocom_shop - dont work

@amarilindra
Copy link

@amboutwe

Canonical links and rel="prev" and rel="next" are removed on pages with "noindex" meta tag. Is there any way to force add them?

@ghaydtner
Copy link

When I go to an URL like myblog.com/blog/mypost/?what-is-my-canonical that has a query string on it, the canonical will be set to myblog.com/blog/mypost/?what-is-my-canonical.
In my eyes, the best canonical here would be myblog.com/blog/mypost/.
Is there a way to get rid of query strings for canonicals for blog posts?

@Suny-ticket
Copy link

Can we remove canonicals for only one post type (any specific)?
I am creating custom canonicals but Yoast gives me another canonical also, I want to replace canonical for that post-type generated by Yoast, not for other post types & pages.

@amboutwe
Copy link
Author

amboutwe commented Jan 5, 2023

@Suny-ticket Yes, the remove_post.php is for a single post, but that can be adjusted to be wider (all content matching specific criteria) depending on your needs. These are just a few examples so you or your developer have a starting point for the customization.

@malkasun
Copy link

malkasun commented Aug 9, 2023

please pay attention to this @amboutwe I have added canonical links to all pages of my website. Let's take the home page as an example.
Let's say https://sample.com is entered there.
See the image below.
image

When you go to the view page source on the home page of the website, it is shown as follows
<link rel="canonical" href="//sample.com/" class="yoast-seo-meta-tag" />
See the image below.
image

Despite this, when the PageSpeed Insights test is run in the Google search console, the following error is displayed in the SEO section.
Document does not have a valid rel=canonicalIs not an absolute URL (//sample.com/)
It is shown in the picture below.
image

How to solve this problem?
I think the problem is that the https: part before the double slash // of //sample.com is not showing up in the view page source.

@amboutwe
Copy link
Author

amboutwe commented Aug 9, 2023

This is not the proper place to request support. That said, I've seen this before and it's not caused by Yoast SEO. You have something in your setup that converts absolute links (with the https) to relative links (without the https).

Please check out our extensive help section or visit the free support forum. If you require further support, upgrading to our premium version provides you with access to our support team.

@rhaglennydd
Copy link

I was working on a site that forces www, but for some reason not every page had "www." in the canonical URL. Most of them did, but I found a few, including the home page, that didn't. We are running the latest Yoast SEO (20.13). I had to write this filter:

add_filter(
    'wpseo_canonical',
    function (string $canonical_url): string {
        if ($canonical_url && !str_starts_with($canonical_url, WP_HOME)) {
            $canonical_url =
                preg_replace('#^https?://[\w.-]+#', WP_HOME, $canonical_url);
        }

        return $canonical_url;
    },
);

@malkasun
Copy link

Finally I solved this problem. The reason was "Automatic HTTPS Rewrites" in AMP plugin and cloudflare and "Automatic HTTPS Rewrites" in WProket plugin where cloudflare was connected.
After removing the AMP plugin and turning off "Automatic HTTPS Rewrites", the problem was solved. This AMP plugin was one of the newspaper theme plugins.
image
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment