How can I make a dynamic sitemap in Nextjs 14?

301 Views Asked by At

I have this code snippet for a dynamic sitemap for my blogpost website in nextjs 14. This works perfectly fine in development but in build or prod, this does not generate a dynamic sitemap even if i wait for 60 seconds. I also noticed that when I deployed my project with this sitemap code snippet, the build logs always says that the sitemap is "prerendered static". What do I do to make my sitemap dynamic and updates for a period of time? Im stuck with this project for 3 days now because of this. If anyone knows an answer or two, please comment out. Thank you

import { CategoryInterface, PostInterface } from "@/commons/types"
import { getAllCategories, getAllPosts } from "@/lib/get-requests"
import { MetadataRoute } from "next"

export const revalidate = 60

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
    const baseUrl = "https://www.mywebsite.com"

    const { categories } = await getAllCategories()
    const { posts } = await getAllPosts()

    const categoryUrls = categories
        ?.filter((category: CategoryInterface) => category.isPublished)
        ?.map((category: CategoryInterface) => ({
            url: category.liveUrl,
            lastmodified: new Date(),
            priority: 1,
            changeFrequency: "daily",
        }))

    const postUrls = posts?.filter((post: PostInterface) => post.isPublished)?.map((post: PostInterface) => ({
        url: post.liveUrl,
        lastmodified: post.updatedAt,
        priority: 1,
        changeFrequency: "daily",
    }))

    return [
        { 
            url: baseUrl,
            lastmodified: new Date(),
            priority: 1,
            changeFrequency: "daily",
        },
        { 
            url: `${baseUrl}/blogs`,
            lastmodified: new Date(),
            priority: 1,
            changeFrequency: "daily",
        },

        ...postUrls,
        ...categoryUrls,
    ]
}

I have read the nextjs documents for the "dynamic" sitemap but it's not generating dynamically. I also tried different ways like:

import { CategoryInterface, PostInterface } from '@/commons/types';
import { getAllCategories, getAllPosts } from '@/lib/get-requests';
import { GetServerSideProps } from 'next'

export default function Sitemap() {
    return null
}

export const getServerSideProps: GetServerSideProps<{}> = async ({req, res}) => {
    res.setHeader(
        'Content-Type', 'text/xml',
    );
    const xml = await generateSitemap()

    res.write(xml);
    res.end()
    return {
        props: {},
    }
}

async function generateSitemap(): Promise<string> {
    const baseUrl = "https://www.mywebsite.com"
    
    const { categories } = await getAllCategories()
    const { posts } = await getAllPosts()

    return `
    <?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
        <url>
            <loc>${baseUrl}</loc>
            <lastmod>${new Date()}</lastmod>
            <changefreq>daily</changefreq>
            <priority>1</priority>
        </url>
        <url>
            <loc>${baseUrl}/blogs</loc>
            <lastmod>${new Date()}</lastmod>
            <changefreq>daily</changefreq>
            <priority>1</priority>
        </url>
        ${posts?.filter((post: PostInterface) => post.isPublished)?.map((post: PostInterface) => {
            return `
            <url>
                <loc>${post.liveUrl}/blogs</loc>
                <lastmod>${post.updatedAt}</lastmod>
                <changefreq>daily</changefreq>
                <priority>1</priority>
            </url>
            `
        }).join('')}

        ${categories?.filter((category: CategoryInterface) => category.isPublished)?.map((category: CategoryInterface) => {
            return `
            <url>
                <loc>${category.liveUrl}/blogs</loc>
                <lastmod>${category.updatedAt}</lastmod>
                <changefreq>daily</changefreq>
                <priority>1</priority>
            </url>
            `
        }).join('')}
    </urlset>
    `
}

but this one does not show in my development. so i did not use this one.

1

There are 1 best solutions below

0
Kcj On

Are you using app router? Try adding this to make the page dynamic.

export const dynamic = 'force-dynamic'