I want to use https://github.com/iamvishnusankar/next-sitemap to generate Sitemap.
However, when I use it normally like:
next-sitemap.js
module.exports = { siteUrl: 'https://example.com', generateRobotsTxt: true, }
It generates sitemap for all my posts.
Although, in my .mdx
files, I have a published
key to know whether the post is a draft
or it is ready to be published
like:
export const meta = { title: 'Hello World', date: '2020-09-11T14:54:37.229Z', tags: ['hello', 'world'], author: 'Akshay Kadam', published: false, } # Hello World This is my first blog post, not yet ready to be published
How do I read the published
key from .mdx
file so I can generate sitemap of only published: true
posts?
Note: I can’t use https://www.npmjs.com/package/gray-matter because my .mdx
files have an exported object as metadata.
Advertisement
Answer
I used a custom sitemap generator like:
scripts/build-sitemap.js
const fs = require('fs') const glob = require('fast-glob') const prettier = require('prettier') const { getAllPublishedEssays } = require('@/utils/essay/getAllEssayPreviews') const { getAllPublishedTutorials } = require('@/utils/tutorial/getAllTutorialPreviews') const posts = [...getAllPublishedEssays(), ...getAllPublishedTutorials()] const config = { siteUrl: 'https://akshaykadam.com', changefreq: 'daily', priority: '0.7', lastmod: new Date().toISOString(), } const robotsTxt = ` User-agent: * Allow: / Host: ${config.siteUrl} Sitemap: ${config.siteUrl}/sitemap.xml `.trim() const main = async () => { const prettierConfig = await prettier.resolveConfig('./prettier.config.js') const sitemap = ` <?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"> ${posts .map((post) => { return ` <url> <loc>${`${config.siteUrl}/${post.slug}`}</loc> <changefreq>${`${config.changefreq}`}</changefreq> <priority>${`${config.priority}`}</priority> <lastmod>${`${config.lastmod}`}</lastmod> </url> ` }) .join('')} </urlset> ` const formatted = prettier.format(sitemap, { ...prettierConfig, parser: 'html', }) fs.writeFileSync('public/sitemap.xml', formatted) fs.writeFileSync('public/robots.txt', robotsTxt) } main()
getAllEssayPreviews.ts
export const getAllPublishedEssays = (): Array<{ slug: string module: any }> => importAll(require.context('../../pages/essay/?rss', true, /.mdx$/)) .filter((p: Post) => p.module.meta.published) .sort((a: Post, b: Post) => dateSortDesc(a.module.meta.date, b.module.meta.date))
next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: process.env.ANALYZE === 'true', }) module.exports = withBundleAnalyzer({ . . . webpack: (config, options) => { . . . if (!options.dev && options.isServer) { const originalEntry = config.entry config.entry = async () => { const entries = { ...(await originalEntry()) } entries['./scripts/build-rss'] = './scripts/build-rss.js' entries['./scripts/build-sitemap'] = './scripts/build-sitemap.js' return entries } } return config }, })