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 upgrade
upgrade 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
.theme
to.theme-legacy
. After renaming, don't forget to delete generate contents like/.nuxt
,/node_modules
etc. because too many changes will appear.
nuxi
automatically install nuxt with the latest version. don't forget to set version tov3.7.4
inpackage.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
.env
file is renamed, your config such asapp.baseUrl
may be corrupted etc.