N
Nuxt•5mo ago
dreamland

SPA w/ SEO or SSG + nitro?

i'm creating a SPA and i've opted to use nuxt because of the ease of development (especially for the frontend devs in my team, that automatically get an up to date server when they pull) my expectation was that the data from useSeoMeta from app.vue would be included in the build even with ssr: false, but apparently all seo meta data is disregarded in that case (https://stackoverflow.com/questions/74070241/what-is-the-difference-between-ssrfalse-vs-targetstatic-in-nuxtjs) so i've tried to use SSG and running nitro separately, but i keep running into problems.. i've been reading about it the entire afternoon and evening. it seems like such a basic usecase, but i can't find anything about it. i feel like i'm missing something obvious. any pointers appreciated
Stack Overflow
What is the difference between 'ssr:false' vs 'target:static' in Nu...
To generate a static site using NuxtJS, it seems there are 2 options to set: ssr:false and target:static inside the NuxtJS config file (nuxt.config.js) which practically do the sme thing? Why both of
26 Replies
manniL
manniL•5mo ago
but apparently all seo meta data is disregarded in that case
Yup, except the defaults from your nuxt config ssr: true (default) + using nuxt generate is the easiest way to go there you can also only prerender the sites necessary
dreamland
dreamland•5mo ago
thanks that solves the SPA ssr: false the SSG case with nuxt generate is more interesting and applicable in my case thought, but i'm having some issues, i'll post a new thread here is one of the problems with nuxt generate: https://discord.com/channels/473401852243869706/1215088275409076274 how to run the nitro backend and serve the static output in parallel?
manniL
manniL•5mo ago
nuxt build + setting prerender routes 🙂
dreamland
dreamland•5mo ago
i think there is a misunderstanding. you were talking about nuxt generate (aka SSG), and i was asking about serving the SSG static output along with running the nitro server do you mean setting prerender routes on a per route basis? i want all routes to be prerendered. nuxi build --prerender seem more appropriate in that case, but that is experimental https://nuxt.com/docs/api/commands/build i feel like i'm trying to achieve a very basic usecase, but it feels like i'm fighting nuxt to do something it's not supposed to
manniL
manniL•5mo ago
do you mean setting prerender routes on a per route basis? i want all routes to be prerendered. nuxi build --prerender seem more appropriate in that case, but that is experimental https://nuxt.com/docs/api/commands/build
--prerender seems like a decent option. You can also configure to prerender all routes that the crawler can find at build time
Nuxt
nuxi build ¡ Nuxt Commands
Build your Nuxt application.
manniL
manniL•5mo ago
i feel like i'm trying to achieve a very basic usecase, but it feels like i'm fighting nuxt to do something it's not supposed to
No, this is an absolutely reasonable approach ☺️
dreamland
dreamland•5mo ago
i'll try to keep my sanity, thanks for your help!
manniL
manniL•5mo ago
no problem at all! BTW: It is not necessary to prerender all routes if you want an SPA it is enough to provide an index.html and "forward" everything onto that through your platform (e.g. netlify and vercel do that by default with a 404 or 200.html) you only need to prerender all if you need SSG and the content in the HTMl
dreamland
dreamland•5mo ago
yea the benefit of prerendering is that pages can have their one meta tags for search engine results essentials i have a SPA part and a static part / (SPA) /somePage (frontend routed) /help/someTopic (static with custom meta tags)
manniL
manniL•5mo ago
the benefit of prerendering is that pages can have their one meta tags for search engine results
Yes, but they are static then unless you use some ClientOnly components in there to make a part of it non-static
dreamland
dreamland•5mo ago
yes i do that i also have a custom loading indicator.. i'd like to use the default ~/app/spa-loading-template.html but unforunately that is only available when using ssr: false, which is not what i want, because.. well you know what happens, it's not SSR-ed, hence no custom meta tags on the routes
manniL
manniL•5mo ago
well you know what happens, it's not SSR-ed, hence no custom meta tags on the routes
Yes, that's why SSR is helpful 😄 I wonder, why not going with dynamic SSR then?
dreamland
dreamland•5mo ago
i'll try to break it down by what my goal is and by what i gathered about the features that are offered by the different approaches my goal SPA part of the site 🎯 static small size initial html (to show something as soon as possible) 🎯 loading indicator (this is not really a goal, more like a necessary evil to show something as soon as possible) 🎯 api (nitro) 🎯 meta tags for "/" route static part of the site 🎯 static initial html 🎯 custom meta tags per route approaches SPA ✔️ static small size initial html ✔️ loading indicator (~/app/spa-loading-template.html) ✔️ api (nitro) ✔️ meta tags for "/" route ❌ custom meta tags per route SSG ✔️ static initial html ✔️ custom meta tags per route ❌ api (nitro) (?) dynamic SSR ❌ static initial html (to show something as soon as possible) ✔️ custom meta tags per route ✔️ api (nitro) ➖ SSR performance paranoia (currently 60k users, aiming for millions very soon) ➖ SSR feels like losing ownership over network traffic prerender SSR ✔️ static initial html with control over size through ClientOnly ➖ needs custom loading indicator ✔️ custom meta tags per route ✔️ api (nitro) as you can see the downsides of dynamic SSR are more subjective than objective for a side project dynamic SSR would be just fine, but for this project i prefer to eliminate uncertainties
Romi
Romi•5mo ago
what did you end up choosing
dreamland
dreamland•5mo ago
well as only 1 of the options has no ❌ blockers, i chose: prerender SSR all pages with <ClientOnly> in "SPA" pages + custom loading screen
routeRules: {
"/**": { prerender: true },
}
routeRules: {
"/**": { prerender: true },
}
<!-- some SPA page -->
<template>
<!-- ready is a ref from the custom loading screen logic -->
<ClientOnly v-if="ready">
<!-- page -->
</ClientOnly>
</template>
<!-- some SPA page -->
<template>
<!-- ready is a ref from the custom loading screen logic -->
<ClientOnly v-if="ready">
<!-- page -->
</ClientOnly>
</template>
this allows custom SEO meta tags per route and control over static initial html size static small size initial html for "SPA" pages static large size initial html for static pages
Romi
Romi•5mo ago
Thanks, so does this allow each page to have its own meta date?
dreamland
dreamland•5mo ago
this allows custom SEO meta tags per route
yes per route aka page
Romi
Romi•5mo ago
So is your SSR set to true? having troubles trying to implemet this
dreamland
dreamland•5mo ago
yes
Romi
Romi•5mo ago
hmm when I added
routeRules: {
"/**": { prerender: true },
}
routeRules: {
"/**": { prerender: true },
}
it broke my site lol
Romi
Romi•5mo ago
and getting following error on my slug.vue
No description
dreamland
dreamland•5mo ago
that doesn't seem to be related, works for me
No description
Romi
Romi•5mo ago
strange
dreamland
dreamland•5mo ago
only reason i can think of why prerender would not work if there are some useState refs that are not initialized at build time, and then when it tries to render some component it gets undefined and breaks
Romi
Romi•5mo ago
maybe let me check I am using Storyblok api to fetch data
dreamland
dreamland•5mo ago
the solution of a lot of things it to try to make it work in a sample project, then your can compare it to your main project