Generate sitemap according prismic data in Nuxt

Hello there :v:
I'm guessing some of you have some experience with generating Sitemap for your project.
I'm having a Nuxt ( SSR full static ) project.
I'm using @nuxtjs/prismic
and @nuxtjs/sitemap module.

The sitemap module does not generate dynamic pages therefor we need to asynchronously retrieve all the pages we have on the website and process the data into a format required by the sitemap module.

I'm guessing that I need to write some build module where I would have access to prismic and then generate and write the desired data format.

Help me please to understand how to import or access prismic from module level so I can write the desired logic.

What are you using for deployment?

If you are using Netlify, the easiest way is to just use the Netlify Sitemap Plugin.

Best
Aleks

In nuxt.config.js add:

const Prismic = require("@prismicio/client");

And in sitemap configuration block:

sitemaps: [
      {
        path: "/sitemap-pages.xml",
        routes: async () => {
          const pages = await getData("page");
          return [...pages.map((i) => `/${i.uid}`)];
        },
      },
    ],

In your case names maybe different, but I hope you've got the idea :slight_smile:

2 Likes

I did as you suggest in your code and it works partially.
All of my static pages are probably rewritten and are missing data, however dynamic pages are filled correctly. Here how my sitemap looks

@martingjorceski, did you know that you can create the route for your Nuxt project using a Route Resolver?

With @nuxtjs/prismic you can add a routes option in the prismic.apiOptions configuration object and pass a similar object as you are doing with the other plugin.

This thread has been closed due to inactivity. Flag to reopen.

Project details:

  • "@nuxtjs/prismic": "^1.3.1"
  • "nuxt": "^2.15.7"
  • "typescript": "^4.3.5"
  • "@nuxtjs/sitemap": "^2.4.0"

I'm using the repeatable type in Prismic for pages such as policy and blog pages. I want to make sure the routes are generated in my Nuxt project and appear in the sitemap. The sitemap works without any of the below code but it doesn't show the policy routes.

// nuxt.config.js
generate: {
  async routes () {
    let generatedRoutes = []

    // Policy pages
    let policies = await $prismic.api.query(
      $prismic.predicates.at('document.type','policy')
    )
    policies = policies.results.map(page => page.uid)
    policies.forEach(policyUid => {
      generatedRoutes.push(`/policies/${policyUid}`)
    });

    return generatedRoutes
  }
}

But I'm getting an error when accessing /sitemap.xml, I get a $prismic is not defined error. I felt adding const { $prismic } = require('@nuxtjs/prismic') would have resolved this:

// nuxt.config.js
generate: {
  async routes () {
    const { $prismic } = require('@nuxtjs/prismic')
    let generatedRoutes = []

    // Policy pages
    let policies = await $prismic.api.query(
      $prismic.predicates.at('document.type','policy')
    )
    policies = policies.results.map(page => page.uid)
    policies.forEach(policyUid => {
      generatedRoutes.push(`/policies/${policyUid}`)
    });

    return generatedRoutes
  }
}

But the error is now Cannot read property api of undefined. Any ideas of getting around this?

Hi Jack,

Thanks for reaching out; for me, this issue can be because you are supplying an async function 'async routes ()' and not returning a promise such as what is mentioned in the docs:

Please let me know if that doesn't fix the issue to try to dig deeper.

Best,
Fares

Another point here could be that you need to instantiate the Prismic client where you can't use the $prismic directly; you might need to use asyncData to client API instance in Nuxt such as

meanwhile I'm going to do some research and I will come back to you if I get an info.

Hi Fares, they don't seem to do the trick. Thank you for helping. It appears the Nuxt config doesn't recognise the $prismic object. The way around this would be to install @prismicio/client and use Prismic.client() to query the content rather than $prismic.api.query() from @nuxtjs/prismic. This seems more of a @nuxtjs/prismic issue, but the GitHub issues tab directed me here for this kind of general query.

Many thanks,
Jack

Hey Everyone,

Since all your static routes are already generated for you by Nuxt and it's crawler, you can just take this information and create your sitemap from this information.

@tbenniks explains how to do this in his blog post and youtube video:

Thanks.

1 Like

Thank you for the response. This is my bad, it looked as though the issue was with the sitemap module but it actually seems to be an issue with the Nuxt prismic module. See bug - $prismic object not recognised in nuxt.config.(js|ts) · Issue #146 · nuxt-community/prismic-module · GitHub

Yeah, I don't know if it's a bug as it's just not designed to work that way. I can see you got a response in the thread too.

Anyway, the best way to create your sitemap is to use the already generated routes as described above.

Happy coding. :slight_smile:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

I am facing the same issue as described above. I'm not able to generate a sitemap that includes dynamic data from Prismic.

I am running:
"nuxt": "^2.0.0",
"@nuxtjs/sitemap": "^2.0.1",
"prismic-javascript": "^3.0.2",

Here are the contents of my files:

# nuxt.config.js
const Prismic = require("@prismicio/client")

buildModules: [
   ...,
    ['@nuxtjs/prismic', {
      endpoint: 'https://my-prismic-website.cdn.prismic.io/api/v2',
      modern: true,
      apiOptions: {
        routes: [
          {
            type: 'blog_article',
            path: '/blog/prismic/:uid',
          },
        ],
      },
    }],
   ...,
   sitemap: {
    hostname: process.env.NUXT_ENV_RC_HOSTNAME,
    gzip: true,
  }
   ...
   generate: {
    routes () {
      const client = Prismic.client('my-prismic-website')
      const pages = client.query(Prismic.Predicates.at('document.type', 'blog_article'))
        .then(res => {
          return res.results.map(page => {
            return '/blog/prismic/' + page.uid
          })
        })
      return pages
    }
  }

The app runs as expected but I get a weird error in my sitemap.xml page stating TypeError: Only absolute URLs are supported.

I have also tried defining the routes inside of the sitemap property like this:

sitemap: {
  ...,
  routes: async () => {
        const client = Prismic.client('my-prismic-website')
        const pages = client.query(Prismic.Predicates.at('document.type', 'blog_article'))
          .then(res => {
            return res.results.map(page => {
              return process.env.NUXT_ENV_RC_HOSTNAME + '/blog/' + page.uid
            })
          })
        return pages
  }

(I even tried both with and without the process.env.NUXT_ENV_RC_HOSTNAME)
But I always get the exact same error TypeError: Only absolute URLs are supported.

Could you take a look and see what I could be missing?

Here's some additional stack trace for the error, if it helps

ERROR  Only absolute URLs are supported                                                                   8:51:35 PM

  at getNodeRequestOptions (node_modules/node-fetch/lib/index.js:1327:9)
  at node_modules/node-fetch/lib/index.js:1450:19
  at new Promise (<anonymous>)
  at fetch (node_modules/node-fetch/lib/index.js:1447:9)
  at fetch (node_modules/cross-fetch/dist/node-ponyfill.js:10:20)
  at fetchRequest (node_modules/@prismicio/client/cjs/@prismicio/client.js:997:24)
  at DefaultRequestHandler.request (node_modules/@prismicio/client/cjs/@prismicio/client.js:1046:9)
  at HttpClient.request (node_modules/@prismicio/client/cjs/@prismicio/client.js:1057:29)
  at node_modules/@prismicio/client/cjs/@prismicio/client.js:1079:27
  at DefaultApiCache.get (node_modules/@prismicio/client/cjs/@prismicio/client.js:956:19)
  at run (node_modules/@prismicio/client/cjs/@prismicio/client.js:1074:25)
  at node_modules/@prismicio/client/cjs/@prismicio/client.js:1095:13
  at new Promise (<anonymous>)
  at HttpClient.cachedRequest (node_modules/@prismicio/client/cjs/@prismicio/client.js:1094:16)
  at Api.get (node_modules/@prismicio/client/cjs/@prismicio/client.js:1131:32)
  at DefaultClient.getApi (node_modules/@prismicio/client/cjs/@prismicio/client.js:1232:25)
  at DefaultClient.query (node_modules/@prismicio/client/cjs/@prismicio/client.js:1241:21)
  at routes (nuxt.config.js:181:28)
  at promisifyRoute (node_modules/@nuxtjs/sitemap/lib/cache.js:59:17)
  at AsyncCache.load [as _load] (node_modules/@nuxtjs/sitemap/lib/cache.js:18:28)
  at AsyncCache.get (node_modules/async-cache/ac.js:63:8)
  at node:internal/util:441:7
  at new Promise (<anonymous>)
  at AsyncCache.get (node:internal/util:427:12)
  at handler (node_modules/@nuxtjs/sitemap/lib/middleware.js:99:43)
  at call (node_modules/connect/index.js:239:7)
  at next (node_modules/connect/index.js:183:5)
  at next (node_modules/connect/index.js:161:14)
  at next (node_modules/connect/index.js:161:14)
  at next (node_modules/connect/index.js:161:14)
  at nuxt.options.serverMiddleware.push.route.route (/Users/miguelmarques/Desktop/Remote%20Crew%20Repos/rc-website/node_modules/@nuxtjs/tailwindcss/dist/module.mjs:231:9)
  at call (node_modules/connect/index.js:239:7)
  at next (node_modules/connect/index.js:183:5)
  at redirectSSL (node_modules/redirect-ssl/index.js:42:12)
  at call (node_modules/connect/index.js:239:7)
  at next (node_modules/connect/index.js:183:5)
  at next (node_modules/connect/index.js:161:14)
  at WebpackBundler.middleware (node_modules/@nuxt/webpack/dist/webpack.js:1923:5)
  at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Nevermind, I figured out the dumb mistake. For some reason I was passing the name of the project instead of the entire url here:
const client = Prismic.client('my-prismic-website')
instead of
const client = Prismic.client('https://my-prismic-website.cdn.prismic.io/api/v2')

3 Likes