Skip to content
This repository has been archived by the owner on Apr 6, 2023. It is now read-only.

feat(nuxt 3): support custom router options #3485

Merged
merged 16 commits into from
Mar 15, 2022

Conversation

iamroi
Copy link
Contributor

@iamroi iamroi commented Mar 3, 2022

🔗 Linked issue

#3481

❓ Type of change

  • 📖 Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

Currently there is no way to pass vue-router options. Also, we can't pass the options in nuxt.config as we're trying to avoid serialising functions from it.

I have added a condition to check for app/router.options.ts file in the srcDir and passing it to the router instance when it is created. If the file is not present, the default nuxt.options.router options will be used.

Heres is a sample router.options.ts file

One thing I notice when using the default options is the scrollBehavior option which is deprecated and this will show this error TypeError: scrollBehavior is not a function in the browser. This is because of this line

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

First PR 😇
Love you Nuxt!! ❤️
Please guide what to add to the documentation

@netlify
Copy link

netlify bot commented Mar 3, 2022

✔️ Deploy Preview for nuxt3-docs canceled.

🔨 Explore the source changes: 8f9b995

🔍 Inspect the deploy log: https://app.netlify.com/sites/nuxt3-docs/deploys/6230c53644f0130008147335

@iamroi iamroi changed the title feat: support custom router config file or use default options feat(nuxt 3): support custom router config file or use default options Mar 3, 2022
packages/nuxt3/src/pages/module.ts Outdated Show resolved Hide resolved
packages/nuxt3/src/pages/module.ts Outdated Show resolved Hide resolved
@danielroe
Copy link
Member

danielroe commented Mar 3, 2022

Is there any merit in instead having a file which exports a router rather than just options? e.g.:

export default function () {
  const { baseURL } = useRuntimeConfig().app

  const routerHistory = process.client
    ? createWebHistory(baseURL)
    : createMemoryHistory(baseURL)

  return createRouter({
    history: routerHistory,
    routes
  })
}

That would allow taking full control, passing options, and also implement @nuxtjs/router in Nuxt 3 - see nuxt/nuxt#13330.

@iamroi
Copy link
Contributor Author

iamroi commented Mar 4, 2022

I love the full control comes with this! Please let me know if you want me to make changes accordingly @pi0

packages/nuxt3/src/core/app.ts Outdated Show resolved Hide resolved
packages/nuxt3/src/core/app.ts Outdated Show resolved Hide resolved
packages/nuxt3/src/pages/module.ts Outdated Show resolved Hide resolved
@pi0
Copy link
Member

pi0 commented Mar 8, 2022

Thanks for the updates @iamroi. Other than small comments, looks good to me. I also love idea from @danielroe for also allowing to override entire router, however we might want to introduce it as another feature which is more advanced since means opting-out from any default setup behavior.

packages/kit/src/resolve.ts Outdated Show resolved Hide resolved
Copy link
Member

@pi0 pi0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect!

Copy link
Member

@danielroe danielroe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll now need to update the router schema, with particular attention to making sure it's compatible with both Nuxt 2 and Nuxt 3.

For reference:

export default {
/**
* Configure the router mode.
*
* For server-side rendering it is not recommended to change it./**
* @version 2
*/
mode: 'history',
/**
* The base URL of the app. For example, if the entire single page application is
* served under /app/, then base should use the value '/app/'.
*
* This can be useful if you need to serve Nuxt as a different context root, from
* within a bigger web site.
* @version 2
*/
base: {
$resolve: (val, get) => val ? withTrailingSlash(normalizeURL(val)) : get('app.baseURL')
},

Because we are using the schema to generate defaults, the generated code looks like this:

const configRouterOptions = {
  mode: "history",
  base: "/",
  _routerBaseSpecified: true,
  routes: [],
  routeNameSplitter: "-",
  middleware: [],
  linkActiveClass: "nuxt-link-active",
  linkExactActiveClass: "nuxt-link-exact-active",
  linkPrefetchedClass: false,
  extendRoutes: null,
  scrollBehavior: {},
  parseQuery: false,
  stringifyQuery: false,
  fallback: false,
  prefetchLinks: true,
  prefetchPayloads: true,
  trailingSlash: undefined
}

Note, for example, that scrollBehavior is present in these options - as an object! - which means we get a fatal error when starting a Nuxt app with this PR in place.

We also need to comment the schema values so people know what they can customise in Nuxt 3. For example, scrollBehavior currently says it can be configured with (~/app/router.scrollBehavior.js), which is no longer correct.

@pi0
Copy link
Member

pi0 commented Mar 11, 2022

What about introducing new app.router or vue.router option to avoid conflict with legacy router namespace?

@danielroe
Copy link
Member

danielroe commented Mar 11, 2022

We could make a top level pages key which would also allow people to enable/disable/configure the pages integration?

... or we could explicitly only pick a subset of the keys within router?

@pi0
Copy link
Member

pi0 commented Mar 11, 2022

Dealing with v2 namespace could be tricky for the longer term. As you mentioned scrollBehavior is for example completely different. And i would prefer a closer name to the library for config (also being consistant with router.options file :)

@danielroe
Copy link
Member

Shall we then rename pages module to router to align the schema?

@pi0
Copy link
Member

pi0 commented Mar 11, 2022

pages is actually handling pages/... (while router options could be used without pages/ dir)

@iamroi
Copy link
Contributor Author

iamroi commented Mar 11, 2022

@pi0 let me know if you want me to add vue.router option as an empty array under here.
Just thinking if we need this at all as we're not overriding any vue-router options by default and we have the router.options file for user override 🤔

@pi0
Copy link
Member

pi0 commented Mar 15, 2022

Added a new router.options config for now to avoid conflicting with nuxt2 but also reserve rest of the namespace for shortcut configs in the future.

@pi0 pi0 changed the title feat(nuxt 3): support custom router config file or use default options feat(nuxt 3): support custom router config Mar 15, 2022
@pi0 pi0 changed the title feat(nuxt 3): support custom router config feat(nuxt 3): support custom router options Mar 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants