Javascript is required
Michael Hoffmann LogoMichael Hoffmann

Nuxt Tip: Custom SPA Loading Template for Your Nuxt Application

Michael Hoffmann - Senior Frontend Developer (Freelancer)
Michael Hoffmann
Sep 15, 2023
1 min read
|
7 views
Nuxt
Nuxt Tip: Custom SPA Loading Template for Your Nuxt Application Image

You can use Nuxt with the client-side rendering mode to create a single-page application (SPA). In this mode, Nuxt will only render the application on the client-side. This means that the server will only send a minimal HTML document to the client. The client will then render the application and fetch the data from the API.

When using the client-side rendering mode, Nuxt will display a loading indicator until the application is hydrated. The loading indicator is a simple spinner. You can customize the loading indicator by creating a custom loading component.

Info

Since Nuxt 3.7 this loading indicator is disabled per default. You need to manually enable it by setting the spaLoadingTemplate option to true in your nuxt.config.ts file:

nuxt.config.ts
1
export default defineNuxtConfig({
2
ssr: false, // enables SPA rendering mode
3
spaLoadingTemplate: true, // per default disabled since Nuxt 3.7
4
})

You can place a custom HTML file in ~/app/spa-loading-template.html to customize the loading indicator. The file must contain a single HTML element which will be rendered as the loading indicator. For example, the following code is referenced in the official docs:

app/spa-loading-template.html
1
<!-- https://github.com/barelyhuman/snips/blob/dev/pages/css-loader.md -->
2
<div class="loader"></div>
3
<style>
4
.loader {
5
display: block;
6
position: fixed;
7
z-index: 1031;
8
top: 50%;
9
left: 50%;
10
transform: translate(-50%, -50%);
11
width: 18px;
12
height: 18px;
13
box-sizing: border-box;
14
border: solid 2px transparent;
15
border-top-color: #000;
16
border-left-color: #000;
17
border-bottom-color: #efefef;
18
border-right-color: #efefef;
19
border-radius: 50%;
20
-webkit-animation: loader 400ms linear infinite;
21
animation: loader 400ms linear infinite;
22
}
23
24
\@-webkit-keyframes loader {
25
0% {
26
-webkit-transform: translate(-50%, -50%) rotate(0deg);
27
}
28
100% {
29
-webkit-transform: translate(-50%, -50%) rotate(360deg);
30
}
31
}
32
\@keyframes loader {
33
0% {
34
transform: translate(-50%, -50%) rotate(0deg);
35
}
36
100% {
37
transform: translate(-50%, -50%) rotate(360deg);
38
}
39
}
40
</style>

StackBlitz

You can try it yourself in the following StackBlitz project:


If you liked this Vue tip, follow me on Twitter to get notified about new tips, blog posts, and more. Alternatively (or additionally), you can subscribe to my weekly Vue newsletter:

New Vue & Nuxt tips delivered to your inbox:
I will never share any of your personal data.