Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Canonical URL for prefixed strategy #912

Closed
divine opened this issue Oct 2, 2020 · 13 comments · Fixed by #927
Closed

Canonical URL for prefixed strategy #912

divine opened this issue Oct 2, 2020 · 13 comments · Fixed by #927

Comments

@divine
Copy link

divine commented Oct 2, 2020

Is your feature request related to a problem? Please describe.

Currently prefixed strategy generating* index.html for each page which is solely used for redirection does create a duplicate content. It's not possible without index.html to detect and force redirection.

The problem here is that Google can't decide which is canonical URLs on it's own.

It's now detecting /en as duplicate of / (root) path.

See: https://support.google.com/webmasters/answer/182192?hl=en#3

Describe the solution you'd like

Canonical URL enabled for prefixed strategy as well. It's only enabled for PREFIX_AND_DEFAULT https://github.com/nuxt-community/i18n-module/blob/master/CHANGELOG.md#features-24

Thanks!

@divine
Copy link
Author

divine commented Oct 2, 2020

Just an update.

I don't think that this should be only enabled due to issue with redirection. Actually defining canonical urls are important for avoiding duplicate content. I've nuxt sitemap module as well, however Google just doesn't care as they mention it:

We don’t guarantee that we’ll consider the sitemap URLs to be canonical, but it is a simple way of defining canonicals for a large site, and sitemaps are a useful way to tell Google which pages you consider most important on your site.

More information about canonical urls: https://ahrefs.com/blog/canonical-tags/

Also, I can confirm that they just don't care defined canonical urls in sitemap and the only solution it enable it by default or add option*?

* Yes, I do remember adding option is not the case, maybe enable it by default then? It will only improve SEO for all.

@rchl
Copy link
Collaborator

rchl commented Oct 5, 2020

So this extra index.html file, what would the canonical path be set to for it?

Since that extra, generated page is meant to redirect to a specific locale, and that locale might be different from one that the page was generated for, I think the canonical path there would also be problematic.

I'm not sure what is a proper solution for static hosting in this case. Maybe some dummy page whose purpose is to redirect. But than Nuxt already generates one automatically (200.html) so maybe the hosting should just be configured to use that page by default, instead of this module generating extra pages.

@divine
Copy link
Author

divine commented Oct 5, 2020

So this extra index.html file, what would the canonical path be set to for it?

It should be set to defaultLocale if it exists in i18n configuration.

I'm not sure what is a proper solution for static hosting in this case.

Target server when requested with curl gives page content with default locale, the only missing part is canonical url.
Target static should work in the same way, right? Currently it gives empty content.

I'm interested in resolving this duplicate content.

This is site.com/en which google thinks is a duplicate content of root path.
image

After trying out live test : Google-selected canonical Only determined after indexing but it won't select it on it's own. User provided canonical url will resolve this issue.

image

Thanks!

@divine
Copy link
Author

divine commented Oct 11, 2020

Well, after thinking about this more:

Canonical URL might be enabled for all strategies since this a SEO dependent configuration (like og meta tags).

The only differences would be root path dependent on each strategy.

@rchl what do you think?

@divine
Copy link
Author

divine commented Oct 12, 2020

Here is a draft for canonical URL feature:

Strategy Root path Default any other path Except
no_prefix baseUrl baseUrl + this.$route.path -
prefix_except_default baseUrl baseUrl + this.switchLocalePath(currentLocaleCode) if(currentLocaleCode === defaultLocale) return this.$route.path
prefix baseUrl + defaultLocale baseUrl + this.switchLocalePath(currentLocaleCode) -
prefix_and_default baseUrl + defaultLocale * baseUrl + this.switchLocalePath(currentLocaleCode) -

* Not sure about this? Should it point to default locale or root path since it's using defaultLocale as prefixed version and for root path as well. Current implementation only works when there is a query string and after that it only adds canonical URL.

https://github.com/nuxt-community/i18n-module/blob/b35bc579cb6431953e8473f4bd4fd5dbbed33426/src/templates/seo-head.js#L95-L100

Path Locale Action (shouldAddCanonical)
/fr fr false
/fr?test fr true
/ en false
/en en false

and the resulting canonical path is:

<link data-n-head="ssr" data-hid="canonical-lang-ru" rel="canonical" href="http://site.com/fr?test">

Which is incorrect, query parameters should be stripped out.

Even in this draft switchLocalePath is returning query strings, how to return locale path without query string and current locale? Maybe this.$route.path is a better solution?

@rchl your help is appreciated!

More information about this topic:
https://ahrefs.com/blog/canonical-tags/
https://www.shopify.com/partners/blog/canonical-urls
https://support.google.com/webmasters/answer/139066?hl=en
https://moz.com/learn/seo/canonicalization

Thanks!

@divine
Copy link
Author

divine commented Oct 13, 2020

Another update:

According to canonicalization:

URL Canonical Similar
http://site.com/fr?utm_source=test http://site.com/fr Yes
http://site.com/post?id=1 http://site.com/post No (*?)
http://site.com/post/1?utm_source=test http://site.com/post/1 Yes

* Basically this needs to be documented that query parameters will be stripped out for canonicalization because there is no way to solve this otherwise.

Maybe adding configuration parameter canonical enabled true or false will be better solution to enable it by default however since this is a SEO feature - it's already should be enabled.

Thanks!

@rchl
Copy link
Collaborator

rchl commented Oct 13, 2020

Even in this draft switchLocalePath is returning query strings, how to return locale path without query string and current locale? Maybe this.$route.path is a better solution?

I think that's a good idea to use $route.path. Only that the behavior would have to be different for those extra pages generated for the purpose of redirecting (or for prefixed default route with PREFIX_AND_DEFAULT strategy).

Maybe adding configuration parameter canonical enabled true or false will be better solution to enable it by default however since this is a SEO feature - it's already should be enabled.

I believe there is no way to automatically know whether the query parameter should be included in canonical or not. Probably the best we could do is to allow users to specify that manually per-page somehow.

Current implementation only works when there is a query string and after that it only adds canonical URL.

I think it makes sense to add canonical regardless if the current URL matches canonical or not. At least that's what is recommended in https://ahrefs.com/blog/canonical-tags/ ("self-referential canonical tags").

Also, I think we should enable canonical regardless of whichever strategy is used because it's also meant to disambiguate between URLs with queries and without and those can happen with any strategy. We just need to fix the query problem first.

@divine
Copy link
Author

divine commented Oct 13, 2020

I believe there is no way to automatically know whether the query parameter should be included in canonical or not. Probably the best we could do is to allow users to specify that manually per-page somehow.

We could probably grab something like this as an example?

const getForcedColorMode = route => route.matched[0] && route.matched[0].components.default.options.colorMode

Source is here and used like this:

<template>
  <h1>This page is forced with light mode</h1>
</template>

<script>
export default {
  colorMode: 'light',
}
</script>

This was integrated recently and I also like the idea of using local storage instead of cookies as well.


In this library we could use as an example (I'm not the greatest at naming 😅)

<template>
  <h1>This page is forced to use canonical url with parameters</h1>
</template>

<script>
export default {
  canonicalQueries: true,
}
</script>

We just need to fix the query problem first.

How can I help? I'm not the great at writing complicated tests but I'll try my best.

@rchl
Copy link
Collaborator

rchl commented Oct 13, 2020

We could probably grab something like this as an example?

I was thinking something more like:

<script>
export default {
  seo() {
    return {
      canonicalQueries: ['param1']
    }
  }
}
</script>

because even if we want to include some query in canonical, we don't really want to include all but only specific ones.

How can I help? I'm not the great at writing complicated tests but I'll try my best.

Thanks but I'm on it already.

rchl added a commit that referenced this issue Oct 13, 2020
Also don't trigger warning on using "localePath", "switchLocalePath"
or "localeRoute" with default locale. We need that functionality for
generating canonical tag and it doesn't really hurt to allow that.

Resolves #912
rchl added a commit that referenced this issue Oct 13, 2020
Also don't trigger warning on using "localePath", "switchLocalePath"
or "localeRoute" with default locale. We need that functionality for
generating canonical tag and it doesn't really hurt to allow that.

Resolves #912
rchl added a commit that referenced this issue Oct 13, 2020
Also don't trigger warning on using "localePath", "switchLocalePath"
or "localeRoute" with default locale. We need that functionality for
generating canonical tag and it doesn't really hurt to allow that.

Resolves #912
rchl added a commit that referenced this issue Oct 13, 2020
Also don't trigger warning on using "localePath", "switchLocalePath"
or "localeRoute" with default locale. We need that functionality for
generating canonical tag and it doesn't really hurt to allow that.

Resolves #912
@rchl rchl closed this as completed in #927 Oct 13, 2020
rchl added a commit that referenced this issue Oct 13, 2020
Also don't trigger warning on using "localePath", "switchLocalePath"
or "localeRoute" with default locale. We need that functionality for
generating canonical tag and it doesn't really hurt to allow that.

Resolves #912
@rchl
Copy link
Collaborator

rchl commented Oct 13, 2020

Fixes released in https://github.com/nuxt-community/i18n-module/releases/tag/v6.15.2

@RobbieTheWagner
Copy link

@rchl so did we decide not to have canonicalQueries. We're looking for a way to enable adding query params sometimes.

@rchl
Copy link
Collaborator

rchl commented Aug 31, 2021

Feel free to create a feature request for it. I think we don't have one yet, even if it was discussed here.

@RobbieTheWagner
Copy link

@rchl this is my first attempt #1274 please let me know your thoughts and I am happy to iterate on it! I wasn't sure how to do it on a page by page basis or how to write tests, but hopefully this gets us started!

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

Successfully merging a pull request may close this issue.

3 participants