Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Localized route prefixes behavior induces duplicate content and local switching issues #40344

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

Closed
Pixelshaped opened this issue Mar 2, 2021 · 2 comments

Comments

@Pixelshaped
Copy link

Symfony version(s) affected: 5.2.3, but probably any from 4.1.x

Description
Localized routes that are prefixed with a locale prefix encounter a number of issues:

  1. When all locales are prefixed, the base route is still accessible.
  2. When all locales except the default are prefixed, the default route doesn't switch the locale back to the default langage.

How to reproduce
Say you have a controller method bearing the following annotation:
@Route("/shopping", name="shopping")

Issue 1. When all locales are prefixed, the base route is still accessible
This configuration:

shopping:
    resource: ../../src/Controller/Application/Shopping/
    type: annotation
    prefix:
        fr: '/fr'
        en: '/en'

Will give you 3 routes:

  1. /fr/shopping
  2. /en/shopping
  3. /shopping which is undesired

Issue 2. When the default locale is not prefixed, the default route doesn't switch the locale back to the default langage
When you don't force a prefix for the default locale, as in this configuration:

shopping:
    resource: ../../src/Controller/Application/Shopping/
    type: annotation
    prefix:
        fr: '' # "fr" is the default locale here
        en: '/en'

It will give you 2 routes:

  1. /shopping
  2. /en/shopping

Which is the desired behavior. But another bug appears:

  1. if you visit /shopping, the site is in french
  2. if you then go to /en/shopping, the site switches to english
  3. if you then go to /shopping, the site stays in english

Both A and B issues are undesirable (notably from an SEO standpoint):

  • Issue 1: /shopping is an unwanted duplicate content of /fr/shopping
  • Issue 2: if the bot that visits the website isn't stateless, it can be served english content on a french page (making it a duplicate too, and unreferencing your french page).

Additional context
When routes are declared using the annotation:

 * @Route({
 *     "fr": "/fr/shopping",
 *     "en": "/en/shopping"
 * }, name="shopping")

The issue 1 does not exist. There is no /shopping route.

Same thing goes for a route that wouldn't have the prefix for the default locale:

 * @Route({
 *     "fr": "/shopping",
 *     "en": "/en/shopping"
 * }, name="shopping")

The issue 2 does not exist. The locale switches correctly back to fr when visiting /shopping, as expected.

So it seems the issue lies in the way prefixes are implemented.

@Pixelshaped
Copy link
Author

I understood what was the issue.

My config was declared like this:

default:
    resource: ../../src/Controller/
    type: annotation

shopping:
    resource: ../../src/Controller/Application/Shopping/
    type: annotation
    prefix:
        fr: '/fr'
        en: '/en'

And I thought that declaring a subfolder would override default routing declaration. It does not. So the route is declared twice: once not localized by the configuration named default, which gives /shopping, and once localized in the configuration named shopping, which gives /fr/shopping and /en/shopping

When configured that way:

default:
    resource: '../../src/Controller/**/*'
    exclude: '../../src/Controller/Application/Shopping/**/*'
    type: annotation

shopping:
    resource: ../../src/Controller/Application/Shopping/
    type: annotation
    prefix:
        fr: '/fr'
        en: '/en'

Everything works as expected, both with a prefix for the default locale, or without.

So I guess the issue is more a documentation problem. The exclude configuration parameter is not documented in the Routing section of the documentation (https://symfony.com/doc/5.3/routing.html). Also I stumbled upon the fact that the exclude configuration parameter is not taken into account if the resource parameter does not contain a glob pattern, as mentioned in another issue here: #31587 (comment)

Feel free to close this issue or to attach a documentation label.

@nicolas-grekas
Copy link
Member

Can you maybe submit a change to the doc?

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

No branches or pull requests

4 participants