How to Create a Sitemap when using Next.js
9 replies
Last updated: Jan 8, 2021
G
Anyone know how to create a sitemap when using NextJS with Sanity?
Not a Sanity specific question I know
I found this from Lee Rob
https://leerob.io/blog/nextjs-sitemap-robots
It doesn't generate the paths though just the file name so,
Not a Sanity specific question I know
I found this from Lee Rob
https://leerob.io/blog/nextjs-sitemap-robots
It doesn't generate the paths though just the file name so,
<https://mysite.com/folder/[file]>
Jan 8, 2021, 4:56 PM
We've set it to an API route inside of Next, with this code:
const client = require('../../client') const sm = require('sitemap') const defaultUrls = [ { url: '/', changefreq: 'daily', priority: 1 }, { url: '/pricing', priority: 0.5 }, { url: '/pricing/compare', priority: 0.5 }, { url: '/docs', priority: 0.7 }, { url: '/community', priority: 0.7 }, { url: '/blog/', changefreq: 'weekly', priority: 0.7 }, ] async function getSitemap() { const {routes, blogposts} = await client.fetch(` { "routes": *[_type == "route" && includeInSitemap], "blogposts": *[_type == 'post' && includeInSitemap == true && publishedAt < $now] | order(publishedAt desc) { slug } } `) const urls = routes.filter(({slug = {}}) => slug.current) .reduce((acc, route) => ([...acc, { url: route.slug.current, priority: route.sitemapPriority || 0.5 }]), defaultUrls) const blogUrls = blogposts .filter(({slug = {}}) => slug.current) .map(post => { return { url: `/blog/${post.slug.current}`, priority: 0.5 } }) return sm.createSitemap ({ hostname: '<https://www.sanity.io>', cacheTime: 600000, urls: urls.concat(blogUrls) }) } module.exports = function sitemapXML(req, res, next) { res.setHeader('Content-Type', 'application/xml') getSitemap() .then(result => { res.send(result.toString()) }) .catch(next) }
Jan 8, 2021, 5:03 PM
G
So, do I add this to a scripts folder and call it in the
next.config.jslike in Lee's example
user Y
?Jan 8, 2021, 5:06 PM
P
I got this working a different way. Not sure if it is the best way or not but I am using
getServerSidePropson a page file that is called
sitemap.xml.tsxand set the headers to text/xml.
Jan 8, 2021, 5:36 PM
G
Also what is
includeInSitemapin the query?
Jan 8, 2021, 5:36 PM
G
Could you link an example
user U
?Jan 8, 2021, 5:37 PM
G
import sanity from "@sanity/client"; import groq from "groq"; export default function SiteMap() { return <div>loading</div>; } export async function getServerSideProps({ res }) { const baseUrl = `<https://cwp-www.vercel.app>`; const query = groq`{ "pages": *[_type == 'sitePage']{slug}, "service": *[_type == 'service']{slug}, "people": *[_type == 'person' && title->name != 'Service Ambassador']{slug} , "article": *[_type == 'article']{slug} }`; const client = sanity({ projectId: "YOUR PROJECTID", dataset: "YOUR DATASET", token: "", // or leave blank to be anonymous user useCdn: false, // `false` if you want to ensure fresh data }); const urls = await client.fetch(query); const pages = urls.pages.map((page) => { const slug = page.slug.current === "/" ? "/" : `/${page.slug.current}`; return `${baseUrl}${slug}`; }); const service = urls.service.map((page) => { const slug = `/service/${page.slug.current}`; return `${baseUrl}${slug}`; }); const people = urls.people.map((page) => { const slug = `/people/${page.slug.current}`; return `${baseUrl}${slug}`; }); const article = urls.article.map((page) => { const slug = `/article/${page.slug.current}`; return `${baseUrl}${slug}`; }); const locations = [...pages, ...service, ...people, ...article]; const createSitemap = () => `<?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="<http://www.sitemaps.org/schemas/sitemap/0.9>"> ${locations .map((location) => { return `<url> <loc>${location}</loc> <changefreq>weekly</changefreq> </url> `; }) .join("")} </urlset> `; res.setHeader("Content-Type", "text/xml"); res.write(createSitemap()); res.end(); return { props: {}, }; }
Jan 8, 2021, 5:38 PM
P
That's great
I'll credit you, do you have somewhere I can point to or will just your name there be enough?
user U
, do you mind if I document this on my blog?I'll credit you, do you have somewhere I can point to or will just your name there be enough?
Jan 8, 2021, 6:09 PM
G
Cool!
Jan 8, 2021, 6:16 PM
G
Yea I don’t mind. Just the name would be cool. Thanks!
Jan 8, 2021, 6:17 PM
Sanity– build remarkable experiences at scale
Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.