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

Not playing nice with router.extendRoutes #1280

Open
1 of 2 tasks
hacknug opened this issue Sep 10, 2021 · 9 comments · May be fixed by #1281
Open
1 of 2 tasks

Not playing nice with router.extendRoutes #1280

hacknug opened this issue Sep 10, 2021 · 9 comments · May be fixed by #1281

Comments

@hacknug
Copy link

hacknug commented Sep 10, 2021

Some projects will fetch data from an external source and use router.extendRoutes to create pages based on the source's response contents. In my case I fetch the data from Sanity and, given a _type and slug, I'll generate a page using one of my ignored page components.

Before adding @nuxtjs/i18n to my project, I was able to pass an array of route objects and Nuxt was using to create the pages I wanted. With this module enabled, Nuxt will try to render all of those pages for each of the available locales.

This is what doesn't work as expected (plus I couldn't find any examples of using the module like this). I have a PR ready for review (#1281) that is solving this issue on my local env. Since I'm not familiar with the codebase and all the ins and outs of the module I'm opening this issue first.

Version

@nuxtjs/i18n: v7.0.3
nuxt: v2.15.8

Nuxt configuration

  • Applies to a site deployed to a static server (site generated with nuxt generate)
  • Applies to a site deployed to a server with a Node backend

@nuxtjs/i18n configuration

// nuxt.config.js

const mapPages = ([key, { component, result }]) => ([key, { component: join(__dirname, component), result }])
const pages = { // on my codebase this is a groq query to Sanity
  "legal": {
    "component": "./pages/-legal.vue",
    "result": [
      {
        "_id": "unique-id-value-for-the-document",
        "lang": "en",
        "slug": "cookies-policy"
      },
      {
        "_id": "i18n.unique-id-value-for-the-document.es",
        "lang": "es",
        "slug": "politica-cookies"
      }
    ]
  }
}

const dynamicPages = Object.fromEntries(Object.entries(pages).map(mapPages))

export default {
  buildModules: [
    ['@nuxtjs/i18n', {
      locales: ['en', 'es'],
      defaultLocale: 'en',
      detectBrowserLanguage: false,
      vueI18n: {
        fallbackLocale: 'en',
        messages: {
          en: { welcome: 'Welcome' },
          es: { welcome: 'Bienvenido' },
        },
      },
    }],
  ],

  router: {
    extendRoutes (routes) {
      const buildRoutes = ([key, { result, component }]) => result.map(({ lang, slug, _id }) => {
        const name = _id.includes('i18n.') ? result.find((i) => i._id === _id.split('.')[1]).slug : slug
        const route = _id.includes('i18n.') ? `/${lang}/${slug}` : `/${slug}`
        return { name: `${name}___${lang}`, path: route, component, chunkName: `pages/${key}`, url: route }
      })

      return sortRoutes([
        ...routes,
        ...Object.entries(dynamicPages).map(buildRoutes).flat(),
      ])
    },
  },
}
  • Dont' mind the unnecessary Object.entries(Object.fromEntries()), my config is split in two parts and one of them is shared accross different projects and I just copy/pasted the relevant parts for the issue.

Reproduction Link

https://codesandbox.io/s/test-nuxt-i18n-forked-2us3p

Steps to reproduce

  1. Open the reproduction link
  2. Open the browser URL from CodeSandbox on a new tab
  3. Open the routes section inside vue-devtools, you should se something like this:

Captura de pantalla 2021-09-10 a las 15 52 19

What is Expected?

I expect @nuxtjs/i18n to either:

  • allow me to pass an array of valid routes without messing with them
  • handle everything automagically for me (this might be hard to implement and would require users to provide those routes with everything the module could need to make it work)

What is actually happening?

The module is assuming each of those routes needs their localized counter parts and pushing them to the router. This breaks the theme-switcher functionality and pushes non-existent pages to the router, resulting in one build error for each of those.

It also prefixes the paths with each locale, resulting in some cases in a duplicated locale. Looks like this only happens because the module doesn't expect someone to provide custom routes.


I tried with different name routes, including/excluding the locale on the name route, and a bunch of other things. The approach shown on the config section of this issue is what made the most sense to me since it consist of manually writing the same route Nuxt and the module would generate for me.

@rchl
Copy link
Collaborator

rchl commented Sep 10, 2021

Without investigating too much, maybe it would work for you to set the pages option (https://i18n.nuxtjs.org/options-reference#pages) based on the API response instead?

@hacknug
Copy link
Author

hacknug commented Sep 10, 2021

Without investigating too much, maybe it would work for you to set the pages option (i18n.nuxtjs.org/options-reference#pages) based on the API response instead?

Yeah, that's what I'm using for most pages. I forgot to add some details to justify my setup.

I'm using ignored pages (four different kinds) to generate pages at the root level. They're landings the marketing team uses to onboard new users and I have no way to know where they'll go except at build time when I fetch them from the CMS.

Let me know if this makes it clearer or you have any more questions. I can provide more details if that's the case 👍

@stale
Copy link

stale bot commented Jan 8, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jan 8, 2022
@hacknug
Copy link
Author

hacknug commented Jan 11, 2022

not stale

@stale stale bot removed the stale label Jan 11, 2022
@emielmolenaar
Copy link

emielmolenaar commented Mar 9, 2022

Same issue here, we are using _.vue to fetch pages from an API based on the page path. Together with the prefix_and_default strategy and without a default locale, the route to _.vue is gone. Manually defining that route via extendRoutes isn't working.

@nepster-web
Copy link

is there any progress on this issue?

@smg99
Copy link

smg99 commented Sep 13, 2022

Same issue here, we are using _.vue to fetch pages from an API based on the page path. Together with the prefix_and_default strategy and without a default locale, the route to _.vue is gone. Manually defining that route via extendRoutes isn't working.

+1

@Fillsen
Copy link

Fillsen commented Nov 10, 2022

Same issue

@zhouyupeng
Copy link

try to use hooks like so:

 hooks: {
    "build:extendRoutes": (routes, resolve) => {
      routes.push({
        name: "RouterName",
        path: "/path",
        component: resolve(__dirname, "components/components.vue")
      });
    }
  },

@BobbieGoede BobbieGoede added the v7 label Sep 12, 2023
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.

8 participants