N
Nuxt2mo ago
DamianId

Nuxt 3 - generating dynamic sitemap xml for storyblock

Hello! I installed sitemap module from nuxt modules and I have problem with dynamic generating sitemap for articles. I dont see URL's from dynamic generation on sitemap.xml. I have 5 static routes, and X dynamic routes. I added this code into nuxt config but IDE provide me information that routes is not used:

routes: async () => {
try {
const { useStoryblokApi } = await import('@storyblok/vue');
const storyblokApi = useStoryblokApi();

const version = process.env.NODE_ENV === 'development' ? 'draft' : 'published';
console.log(`[Sitemap] Fetching Storyblok articles with version: ${version}`);

const { data } = await storyblokApi.get('cdn/stories', {
version: version,
starts_with: 'articles/',
per_page: 100
});

if (data && data.stories && data.stories.length > 0) {
console.log(`[Sitemap] Found ${data.stories.length} articles`);

return data.stories.map(story => ({
url: `/articles/${story.slug}`,
lastmod: story.published_at || story.created_at,
changefreq: 'monthly',
priority: 0.8
}));
} else {
console.log('[Sitemap] No articles found in Storyblok');
return [];
}
} catch (error) {
console.error('[Sitemap] Error generating dynamic sitemap entries:', error);
return [];
}
}

routes: async () => {
try {
const { useStoryblokApi } = await import('@storyblok/vue');
const storyblokApi = useStoryblokApi();

const version = process.env.NODE_ENV === 'development' ? 'draft' : 'published';
console.log(`[Sitemap] Fetching Storyblok articles with version: ${version}`);

const { data } = await storyblokApi.get('cdn/stories', {
version: version,
starts_with: 'articles/',
per_page: 100
});

if (data && data.stories && data.stories.length > 0) {
console.log(`[Sitemap] Found ${data.stories.length} articles`);

return data.stories.map(story => ({
url: `/articles/${story.slug}`,
lastmod: story.published_at || story.created_at,
changefreq: 'monthly',
priority: 0.8
}));
} else {
console.log('[Sitemap] No articles found in Storyblok');
return [];
}
} catch (error) {
console.error('[Sitemap] Error generating dynamic sitemap entries:', error);
return [];
}
}
2 Replies
kapa.ai
kapa.ai2mo ago
Hi @DamianId. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- I see you're having issues with generating a dynamic sitemap for your Storyblok content in Nuxt 3. The problem is that the routes option you're using is deprecated in Nuxt 3's sitemap module. For Nuxt 3, you need to use a different approach to add dynamic routes to your sitemap. Here's how you can fix it: Solution Instead of using the routes property directly, you should use the Nitro prerender configuration or add an API source for the sitemap module: Option 1: Using Nitro prerender
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
prerender: {
crawlLinks: true,
routes: ["/", "/articles"]
}
},
// Your other config
})
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
prerender: {
crawlLinks: true,
routes: ["/", "/articles"]
}
},
// Your other config
})
However, this alone might not be enough for dynamic content from Storyblok. According to the knowledge sources, for dynamic pages, you need to add an API source for the sitemap module Link to nuxt-sitemap docs. Option 2: Using a Nuxt plugin to add prerender routes Create a plugin that hooks into the prerender process:
// plugins/storyblok-sitemap.js
export default defineNuxtPlugin(async (nuxtApp) => {
const { useStoryblokApi } = await import('@storyblok/vue');
const storyblokApi = useStoryblokApi();

nuxtApp.hooks.hook('prerender:routes', async (routes) => {
try {
const version = process.env.NODE_ENV === 'development' ? 'draft' : 'published';
console.log(`[Sitemap] Fetching Storyblok articles with version: ${version}`);

const { data } = await storyblokApi.get('cdn/stories', {
version: version,
starts_with: 'articles/',
per_page: 100
});
if (data && data.stories && data.stories.length > 0) {
console.log(`[Sitemap] Found ${data.stories.length} articles`);

data.stories.forEach((story) => {
routes.add(`/articles/${story.slug}`);
});
}
} catch (error) {
console.error('[Sitemap] Error generating dynamic sitemap entries:', error);
}

return routes;
});
});
// plugins/storyblok-sitemap.js
export default defineNuxtPlugin(async (nuxtApp) => {
const { useStoryblokApi } = await import('@storyblok/vue');
const storyblokApi = useStoryblokApi();

nuxtApp.hooks.hook('prerender:routes', async (routes) => {
try {
const version = process.env.NODE_ENV === 'development' ? 'draft' : 'published';
console.log(`[Sitemap] Fetching Storyblok articles with version: ${version}`);

const { data } = await storyblokApi.get('cdn/stories', {
version: version,
starts_with: 'articles/',
per_page: 100
});
if (data && data.stories && data.stories.length > 0) {
console.log(`[Sitemap] Found ${data.stories.length} articles`);

data.stories.forEach((story) => {
routes.add(`/articles/${story.slug}`);
});
}
} catch (error) {
console.error('[Sitemap] Error generating dynamic sitemap entries:', error);
}

return routes;
});
});
Option 3: Using the Kit API You can also use the addPrerenderRoutes function from the Nuxt Kit API in a module:
// modules/storyblok-sitemap.js
import { defineNuxtModule, addPrerenderRoutes } from '@nuxt/kit'

export default defineNuxtModule({
setup: async () => {
try {
const { useStoryblokApi } = await import('@storyblok/vue');
const storyblokApi = useStoryblokApi();

const version = process.env.NODE_ENV === 'development' ? 'draft' : 'published';
const { data } = await storyblokApi.get('cdn/stories', {
version: version,
starts_with: 'articles/',
per_page: 100
});

if (data && data.stories && data.stories.length > 0) {
const routes = data.stories.map(story => `/articles/${story.slug}`);
addPrerenderRoutes(routes);
}
} catch (error) {
console.error('[Sitemap] Error generating dynamic sitemap entries:', error);
}
}
})
// modules/storyblok-sitemap.js
import { defineNuxtModule, addPrerenderRoutes } from '@nuxt/kit'

export default defineNuxtModule({
setup: async () => {
try {
const { useStoryblokApi } = await import('@storyblok/vue');
const storyblokApi = useStoryblokApi();

const version = process.env.NODE_ENV === 'development' ? 'draft' : 'published';
const { data } = await storyblokApi.get('cdn/stories', {
version: version,
starts_with: 'articles/',
per_page: 100
});

if (data && data.stories && data.stories.length > 0) {
const routes = data.stories.map(story => `/articles/${story.slug}`);
addPrerenderRoutes(routes);
}
} catch (error) {
console.error('[Sitemap] Error generating dynamic sitemap entries:', error);
}
}
})
Then add this module to your nuxt.config.ts:
export default defineNuxtConfig({
modules: [
'@nuxtjs/sitemap',
'~/modules/storyblok-sitemap'
],
sitemap: {
// your sitemap configuration
}
})
export default defineNuxtConfig({
modules: [
'@nuxtjs/sitemap',
'~/modules/storyblok-sitemap'
],
sitemap: {
// your sitemap configuration
}
})
The reason your IDE is showing that routes is not used is because this property has been deprecated in Nuxt 3's sitemap module, as mentioned in the Nuxt configuration documentation. Try one of these approaches, and your dynamic Storyblok articles should appear in your sitemap.xml file. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@597666656936001546> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?