Migrations
It is the documentation of the migrations between versions, problems encountered while migrating, solutions to problems and changes.
Nuxt: v3.10.3 👉 v3.12.4
Below you can find a migration checklist;
- [ ] upgrade nuxt: "3.12.4"
- [ ] disable inline style feature
- [ ] upgrade babel/eslint-parser: "7.25.1"
- [ ] upgrade mermaid-js/mermaid-cli: "10.9.1"
- [ ] override puppeteer: "22.15.0"
- [ ] upgrade nuxt/content: "2.13.2"
- [ ] upgrade pinia/nuxt: "0.5.3"
- [ ] upgrade pinia: "2.2.0"
- [ ] upgrade sass: "1.77.8"
- [ ] move root css rules before any nested
- [ ] upgrade vue: "3.4.35"
- [ ] disable "vue/no-multiple-template-root"
- [ ] remove wrapper root elements
- [ ] upgrade vue-router: "4.4.3"
- [ ] check linux build
- [ ] add optional rollup dependency
- [ ] update workflow actions to `v4`
- [ ] update workflow node versions to `22`
Node version 22.6 is used to test with given packages
Nuxt Content
/ is no longer prerendered
With Nuxt@3.12.0 / is removed from prerendered routes. Add / to
nitro.prerender.routes if nuxi generate is not working as expected
Disable Inline Styles feature
With Nuxt@3.12, we experienced inconsistency with local and external css
precedence when generating static sites. Local css files added in
nuxt.config.ts is now inlined before external styles when a static site
is generated and causes issues when overriding external styles. Add following
config to nuxt.config.ts to disable inlining css files.
export default defineNuxtConfig({
...
features: {
inlineStyles: false
}
}
Vue 3
Vue 3 multiple root elements
Vue 2 reguired single root element when creating components but with Vue 3 we can now use of multiple root elements.
<!-- Vue 3 -->
<template>
<header />
<footer />
</template>
<!-- Vue 2 -->
<template>
<div>
<header />
<footer />
</div>
</template>
Disable "vue/no-multiple-template-root" when using multiple root elements
Precedence change for v-if v-for
With Vue 3, v-if will have higher precedence when used together with v-for
within the same element.
Missing Vite @rollup dependency
Upgraded Vite version now creates missing @rollup/rollup-linux... package
error and fails when bulding on linux. Add following section to package.json to
fix this issue.
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "^4.20.0"
}
For further details see Vue 3 Migration Guide
Sass
Nested Before Root Declerations Warning
With recent sass update, a deprecation warning is shown for changing sass behaviour about css declerations appear before root declerations. Move nested declerations below any root declerations to maintain expected css behaviour
/* deprecated */
.example {
color: red;
a {
font-weight: bold;
}
font-weight: normal;
}
/* suggested */
.example {
color: red;
font-weight: normal;
a {
font-weight: bold;
}
}
Nuxt: v3.7.4 👉 v3.10.3
Below you can find a migration checklist;
- [ ] upgrade nuxt with `npx nuxi upgrade`. This will upgrade to the latest
version.
- [ ] upgrade `@babel/eslint-parser`
- [ ] upgrade `@mermaid-js/mermaid-cli`
- [ ] upgrade `@nuxt/content`
- [ ] upgrade `eslint`
- [ ] upgrade `log-symbols`
- [ ] upgrade `sass`
- [ ] upgrade `vue`
- [ ] upgrade `vue-router`
- [ ] use `useSeoMeta` instead of `useHead` for open graph
npx nuxi upgradeupgrade nuxt with the latest version. When we did this update, nuxt had version3.10.3. Only this version is guaranteed to be no issue :smile:
Use useSeoMeta
While preparing the open graph data, we were updating the meta using useHead.
We switched to useSeaMeta which comes with the new versions of Nuxt.
useSeoMeta({
ogTitle: ...,
ogDescription: ...
});
instead of
useHead({
meta: [
{ hid: "og:title", property: "og:title", content: ... },
{ hid: "og:description", property: "og:description", content: ... }
]
});
Node
Nuxt v3.7.4 requires Node version v18 and above to work but we've decided
to use v20. Make sure you have v20 installed in your local machine.
Nuxt: v3.4.1 👉 v3.7.4
First we tried to upgrade to the new version of nuxt with upgrades, but the
resulting conflicts got too complicated, you can see the upgrade process in
Package Upgrades. So we proceeded by
creating a new nuxt project with the latest version of nuxt-kit.
Below you can find a migration checklist;
- [ ] upgrade node version on workflow
- [ ] move `.theme` to `.theme-legacy`
- [ ] create nuxt project (v3.7.4)
- [ ] update `app.vue` code
- [ ] install `nuxt-content` module & add as module in `nuxt.config.ts`
- [ ] add dynamic page & create `.md` file in `/content` directory for demo
- [ ] Disable `headings.anchorLinks`
- [ ] install `sass` -> move assets from old project -> add styles in
`nuxt.config.ts`
- [ ] move `.env` files from old project
- [ ] add prefix to constants in `.env` file
- [ ] update `runtimeConfig.public` (for `.env`)
- [ ] move prebuild from old project
- [ ] update `config.yml` for puppeteer warnings
- [ ] add prebuild dependencies (`log-symbols`, `mermaid....`)
- [ ] set all components global `true`
- [ ] move all pages & and component from old project
- [ ] move transformers & modules from old projects
- [ ] move modules to under `/modules`
- [ ] add `type` to type imports
- [ ] add empty link to `nitro.prerender.failOnError`
- [ ] make absolute image path
- [ ] move eslintrc config and use only `@nuxtjs/eslint-config-typescript`
- [ ] rename eslint config file as `.eslintrc`
- [ ] add eslint run command to scripts
- [ ] move your scripts from old project
- [ ] remove build stage from scripts
- [ ] set `PayloadExtraction` `false`
- [ ] migration of remaining config in `nuxt.config.ts`
- [ ] Edit incoming old config according to the new config(`.env` config structure etc.)
- [ ] sort configs in `nuxt.config.ts`
Start by running following command
npx nuxi@latest init .theme
During installation it will give you options. When it asks:
package manager: Selectnpm.initialize git repository: selectNo.
Before creating a new project we recommend to move
.themeto.theme-legacy. After renaming, don't forget to delete generate contents like/.nuxt,/node_modulesetc. because too many changes will appear.
nuxiautomatically install nuxt with the latest version. don't forget to set version tov3.7.4inpackage.json.
Change the code in app.vue as follows
<template>
<NuxtLayout name="default">
<NuxtPage />
</NuxtLayout>
</template>
Navigate to the /.theme directory npm run dev run the command.
When you change the code, you will see a blank html page because a page has not been added yet.
Adding Nuxt Content Module
Add content module run following command
npm install @nuxt/content --save-dev
Create new page [...content-page].vue and add this code to under /pages
directory
<template>
<ContentDoc />
</template>
Configure nuxt.config.ts
export default defineNuxtConfig({
devtools: { enabled: true },
modules: [
'@nuxt/content'
],
content: {
// ... options
}
})
The nuxt content module will not be able to access any content at this stage
because it is looking for a file with .md extension under /content.
Therefore, you may see a warning like Document not found on the screen.
If you have come this far, create a markdown file called index.md under the
/content folder. Display your page by saying npm run dev.
Disable headings.anchorLinks option
By default, headers come in link format and the render will be as follows.
<h2 id="head"...>
<a href="#head">
Head
</a>
</h2>
You can do the following configuration to turn it off and render normal text.
export default defineNuxtConfig({
...
runtimeConfig: {
public: {
mdc: {
headings: {
anchorLinks: {
h1: false,
h2: false,
h3: false,
h4: false,
h5: false,
h6: false,
},
},
},
},
},
});
the output is as follows.
<h2 id="head"...>
Head
</h2>
Sass & Css
You can make these configurations to source css to the project from outside.
export default defineNuxtConfig({
...
app: {
head: {
...
link: [
{
rel: "stylesheet",
type: "text/css",
href: "https://mouseless.github.io/brand/assets/css/default.css"
}
]
}
},
css: ["~/assets/styles.css"]
})
to export sass files first install sass
npm install sass --save-dev
then put your style files under /assets
You can then configure nuxt.config.ts as follows to apply your styles and
access style variables from vue files.
export default defineNuxtConfig({
...
vite: {
css: {
preprocessorOptions: {
scss: {
additionalData: "@import \"@/assets/variables.scss\";"
}
}
}
},
css: ["~/assets/styles.scss"]
})
.env.* files
By adding environment files, you can export these files during build and use your constant values during build or runtime.
After getting your env files from the old project, give the relevant .env
files to the places you want in the scripts in package.json to apply them to
the project.
"dev": "npx nuxi dev --dotenv .env.local"
If you write your constant values with the prefix NUXT and NUXT_PUBLIC in
your env file, nuxt will match them automatically.
NUXT_PUBLIC_BASE_URL=/
must have a match in runtimeConfig.public for automatic mapping. It should
be as follows.
export default defineNuxtConfig({
runtimeConfig: {
public: {
baseUrl: ""
}
},
});
To access it from somewhere other than runtimeConfig, you can call it as
process.env.NUXT_PUBLIC_BASE_URL.
Prebuild
In the setup phase with prebuild, we prepare the markdowns at the root and put them under content. We also prepare the corresponding pages and pull the markdown content in these pages and render them.
After prebuild make sure that the folder where the public files are moved
from nuxt.config.ts is set correctly.
export default defineNuxtConfig({
...
dir: {
public: ".public"
},
})
Don't forget to install the dependencies of the prebuild.
npm install log-symbols --save-dev npm install @mermaid-js/mermaid-cli --save-dev
config.yml
When you get the prebuild from your old project or when you write a new one,
you can remove puppeteer warnings by saying config.headless: new while
extracting mermaid diagrams in config.yml.
Components
You must do this configuration to access globally when writing and using the component.
export default defineNuxtConfig({
...
components: {
dirs: [{ global: true, path: "~/components/Prose" }, "~/components"]
},
})
New module & Nuxt Content transformer
To intervene when nuxt content reads markdowns and converts them to html
object, we need to use the transformer feature of nuxt content, to do
this we need to add it as a module to nuxt.
Nuxt scans the /modules directory and loads them before starting. If you
add them under /modules, you don't need to add those local modules to your
nuxt.config.ts separately.
only nuxt modules should be under
/modules.
To see the use of transformer /transformers/optimus-prime.ts
To see how to add a module look nuxt.config.ts.
types
With version v3.7.4 of Nuxt, you must specify Type at the beginning of the
type in type imports as below.
import type { TestNewProps } from '~~/types';
or
import { type TestNewProps } from '~~/types';
Prerender fail
After version nuxt 3.6.2, if a page corresponding to the link cannot be found, it gives generate error.
For solution you can make nitro.prerender.failOnError false or add path to
nitro.prerender.ignore array.
See nuxt.config.ts for example.
Trailing slash
With the new nuxt version, the trailing slash solution we found earlier no
longer works. So we removed the solution for trailing slash in
[...content-page].vue and the router.options.strict: true setting in
nuxt.config.ts.
In the new version, the trailing slash causes problems with images. As a solution, we saw that the change we made in ProseImg reflected the change made in the prerender phase. Therefore, we removed the page part from the paths of the images in the files that are not on the index page in the prerender phase. In this way, it searches the image under the relevant file.
See ProseImg.vue component in components/Prose folder for how to fix
trailing slash issue.
See here for possible img cases. test
Move package.json scripts
You can move your scripts in package.json from your old project. There is no
need to build before Generate and Development, remove it from your scripts.
Eslint
Move your Eslint files and rename the config files to .eslintrc.
The @nuxtjs/eslint-config-typescript module is sufficient by itself, so
other modules have been removed from eslint.
For eslint to work, you can run it in the setup script in package.json with
npx eslint . or if you have added eslint to dependencies, you can run it
with eslint . before build.
Removing the build stage
Removing the build stage we added in generate. Now nuxt builds itself before generate. The build script that we want to run before generate has been removed from the scripts.
PayloadExtraction
We do not want the _payload.json file to be created, so we set
experimental.payloadExtraction to false.
Migration nuxt.config.ts
At this point, if there is a config left in your old file, move your config other than the following.
router.options.strict: true❌typescript.typeCheck: true❌
These configs are no longer needed. Apart from these, you can move your
configurations in runtimeConfig or routes that you want to be generated.
Remember to sort the config in name order after the migration.
Don't forget to review the remaining config from the old project when you migrate. Since the config from the
.envfile is renamed, your config such asapp.baseUrlmay be corrupted etc.