Solve the pre-rendering problem of Vue3 projects more easily with Vite

Original link: https://www.inoreader.com/article/3a9c6e7a78192673

[[toc]]

In the past, Webpack projects often used pre-rendering, and now the team has started to use Vite, so you can refer to a Vite-based Vue 3 pre-rendering demo.

Pre-rendering and static generators are relatively close, you can also refer to my SSG blog to deal with vite-ssg and vite-plugin-pages .

However, Vite itself also provides native support for pre-rendering, and simple pre-rendering can be implemented by writing your own code.

HTML section

At least two comments for the resource injection location need to be added to index.html in the project root directory:

Comment statement effect Is it necessary
<!--preload-links--> Preload resources Yes
<!--app-html--> page content Yes
<!--title--> SEO Optimization: Write Titles no
<!--description--> SEO Optimization: Write a Description no
<!--keywords--> SEO optimization: write keywords no

And change the entry file to entry-client.ts , the original main.ts will be used as the reference when the client and server start.

The complete code is as follows (source: index.html ):

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" href="/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <!--title--> <!--description--> <!--keywords--> <!--preload-links--> </head> <body> <div id="app"><!--app-html--></div> <script type="module" src="/src/entry-client.ts"></script> </body> </html>

In addition to the two required comment statements, the optional part is shown in SEO optimization .

entry file

Ordinary projects use src/main.ts as the entry file, which needs to be transformed into two entries:

Comment statement effect source code
entry-client.ts Client entry View source code
entry-server.ts server entry View source code

The original main.ts is only exported as an entry function, see the source code for details: main.ts

routing

It is no longer necessary to manually configure the routing structure. After the transformation, the routing component of src/views is directly read to generate page routing.

See the source code for details: router

SEO optimization

The purpose of pre-rendering is to do SEO, so you need to configure the three major elements of TKD for SEO in advance. Here I also manage them together in the src/router directory.

For the implementation logic, see the description of the pre-rendering section. Here, the relative path of each page is used to determine the TKD information to be written.

 export default [ { url: '/', title: '首页', description: '这是首页', keywords: ['关键词1', '关键词2'], }, // ... ]

See the source code for details: seo

pre-rendering

The scripts/prerender.ts file executes the prerendering behavior and can be rendered as a static HTML file according to the structure of the routing directory.

Run npm run generate to deploy dist/static as a static site.

Of course I also packaged npm run build to compile all platforms ( Client / Server / Static ) at once.

See: scripts section in package.json .

common problem

Several problems encountered during the transformation process:

Hydration node mismatch

Console error:

 Hydration node mismatch: - Client vnode: div - Server rendered DOM: <!--app-html-->

The warning comes from hydration.ts and can generally be ignored…

Of course, you can also learn more knowledge points: understand-and-solve-hydration-errors-in-vue-js

route jump

Console error:

 Unhandled error during execution of scheduler flush

You need to use the <Suspense /> tag to wrap the route view, see Suspense for details.

 <template> - <!-- <router-view :key="key" /> --> + <router-view :key="key" v-slot="{ Component }"> + <Suspense> + <div> + <component :is="Component" /> + </div> + </Suspense> + </router-view> </template>

This article is reproduced from: https://www.inoreader.com/article/3a9c6e7a78192673
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment