nuxt-modules / i18n

I18n module for Nuxt
https://i18n.nuxtjs.org
MIT License
1.75k stars 483 forks source link

Generating localised routes for page aliases #2604

Open EvilaMany opened 11 months ago

EvilaMany commented 11 months ago

Describe the feature

My app has only 1 page, that should have many possible urls to be resolved by (for SEO purposes). The page should only change some translations depending on url it was resolved by. I created single pages/index.vue and set definePageMeta({ alias... }). But nuxti18n generate only localised route for main page url, not for any of aliases.

For example I have two aliases: /dogs-info /cats-info

In pages/index.vue I set alias as follows definePageMeta({ alias: ["/dogs-info", "/cats-info"] })

I expect that I will have routes: / /pl /es /dogs-info (default locale) /cats-info (default locale) /pl/dogs-info /pl/cats-info /es/cats-info /es/dogs-info

But I have only: / /pl /es

Additional information

Final checks

github-actions[bot] commented 11 months ago

Would you be able to provide a reproduction? 🙏

More info ### Why do I need to provide a reproduction? Reproductions make it possible for us to triage and fix issues quickly with a relatively small team. It helps us discover the source of the problem, and also can reveal assumptions you or we might be making. ### What will happen? If you've provided a reproduction, we'll remove the label and try to reproduce the issue. If we can, we'll mark it as a bug and prioritise it based on its severity and how many people we think it might affect. If `needs reproduction` labeled issues don't receive any substantial activity (e.g., new comments featuring a reproduction link), we'll close them. That's not because we don't care! At any point, feel free to comment with a reproduction and we'll reopen it. ### How can I create a reproduction? We have a couple of templates for starting with a minimal reproduction: 👉 [Reproduction starter (v8 and higher)](https://stackblitz.com/fork/github/BobbieGoede/nuxt-i18n-starter/tree/v8) 👉 [Reproduction starter (edge)](https://stackblitz.com/fork/github/BobbieGoede/nuxt-i18n-starter/tree/edge) A public GitHub repository is also perfect. 👌 Please ensure that the reproduction is as **minimal** as possible. See more details [in our guide](https://nuxt.com/docs/community/reporting-bugs/#create-a-minimal-reproduction). You might also find these other articles interesting and/or helpful: - [The Importance of Reproductions](https://antfu.me/posts/why-reproductions-are-required) - [How to Generate a Minimal, Complete, and Verifiable Example](https://stackoverflow.com/help/mcve)
EvilaMany commented 11 months ago

Reproduction: https://stackblitz.com/edit/github-g8bh9l

BobbieGoede commented 11 months ago

Maybe I misunderstand, but wouldn't the /cats page have different content from the /dogs page? Which would have its own translations?

EvilaMany commented 11 months ago

Not really. My app should have multiple pages with the almost same layout and view, but different urls and translations based on url it resolved by. This differences will lay deeply inside page, in few components. All the other content are the same. Also there are should be possibility to change url to another alias, without rerendering the page itself. I need to rerender only content in components with url based content, but all the other page with inputs etc should save state. So it make sense to make computed-s based on current route.pathname (alias), instead of creating N separate pages

EvilaMany commented 11 months ago

Mostly it's SEO tricks, so I recommend not to find logic here (=

zhouyupeng commented 8 months ago

You can use hooks like this:

export default defineNuxtConfig({
    hooks: {
        'pages:extend'(pages) {
            pages.push({
                name: `dogs-info`,
                path: `/dogs-info`,
                file: resolve(__dirname, 'pages/index.vue')
            });
            pages.push({
                name: `cats-info`,
                path: `/cats-info`,
                file: resolve(__dirname, 'pages/index.vue')
            });
        }
    }
})