I am trying to build a static site using Nuxt 3 and I want the site to be 100% static, without any API calls.
To achieve this I have created my nuxt.config.ts
file as follows.
// only showing relevant configs
export default defineNuxtConfig({
target: 'static',
ssr: true,
hooks: {
async 'nitro:config'(nitroConfig) {
if (!nitroConfig || nitroConfig.dev) {
return
}
const token = process.env.STORYBLOK_API_TOKEN;
let cache_version = 0
// other routes that are not in Storyblok with their slug.
let routes = ['/'] // adds home directly but with / instead of /home
try {
const result = await fetch(`https://api-us.storyblok.com/v2/cdn/spaces/me?token=${token}`)
if (!result.ok) {
throw new Error('Could not fetch Storyblok data')
}
// timestamp of latest publish
const space = await result.json()
cache_version = space.space.version
// Recursively fetch all routes and set them to the routes array
await fetchStories(routes, cache_version)
// Adds the routes to the prerenderer
nitroConfig.prerender.routes.push(...routes)
} catch (error) {
console.error(error)
}
},
},
})
async function fetchStories(routes: string[], cacheVersion: number, page: number = 1) {
const token = process.env.STORYBLOK_API_TOKEN
const version = 'published'
const perPage = 100
try {
const response = await fetch(
`https://api-us.storyblok.com/v2/cdn/links?token=${token}&version=${version}&per_page=${perPage}&page=${page}&cv=${cacheVersion}`,
)
const data = await response.json()
const toIgnore = ['home']
// Add routes to the array
Object.values(data.links).forEach(link => {
if (!toIgnore.includes(link.slug)) {
routes.push('/' + link.slug)
}
})
// Check if there are more pages with links
const total = response.headers.get('total')
const maxPage = Math.ceil(total / perPage)
if (maxPage > page) {
await fetchStories(routes, cacheVersion, ++page)
}
} catch (error) {
console.error(error)
}
}
My build status on Netlify is npm run generate
with Publish directory as dist
.
And in my components, I am using only useAsyncStoryblok
const resp = await useAsyncStoryblok(`home`, {
version: "draft",
resolve_relations: 'FeaturedProjects.projects',
});
projects = resp?.value?.content?.body[0]['projects']
When I do npm run generate && npm run preview
Every time any data is loaded for the first time my API is called which I don't want. Although there are no API calls after the first fetch, I am trying to achieve 0 API calls to fetch content.
I am trying to achieve the following.
- The site should generate all the HTML in the building phase
- No API calls, and the
.html
files should have all the data static for better SEO.
I am also concerned about my API request limit being reached if api keeps getting called.
What am I doing wrong here?
If you want to ensure that your Nuxt 3 static site is truly static and doesn't make any API calls during runtime, you need to avoid using dynamic data fetching methods like useAsyncStoryblok on the client side.
Here are some suggestions to help you achieve your goal:
1-Static Content Generation: Make sure that you are utilizing Nuxt 3's Static Site Generation (SSG) properly. This ensures that your pages are pre-rendered during the build phase, and the resulting HTML files should contain all the necessary data.
Ensure your
nuxt.config.js
is configured for SSG:Also, make sure that the components/pages fetching data are using
fetch
orasyncData
during the build process.2-Avoid Client-Side Data Fetching: If you're using
useAsyncStoryblok
or any other dynamic data fetching method in your components, it might be making API calls during the client-side hydration. To avoid this, you should conditionally fetch data only during the build process.Example using
asyncData
:3-Check API Calls during Build: During the build process, you can check whether API calls are being made. Use the
nuxt generate
command and monitor the output for any unexpected API calls. If you find any, review your components and ensure that data fetching is only happening during the build.4-Static Data Import: If your data is relatively static and doesn't change frequently, consider importing the data directly into your components instead of fetching it during runtime. This way, the data becomes part of the static build.
Example:
By following these suggestions, you should be able to create a Nuxt 3 static site that doesn't make any API calls during runtime and has all the necessary data pre-rendered during the build phase.