question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Async Axios data to @nuxtjs/sitemap breaks when pushed to Vercel

See original GitHub issue

Ok, so let’s say you have a very rudimentary blog:

Post index Live example

<!-- pages/posts/index.vue -->

<template>
  <div v-if="posts">
    <div v-for="(post, index) in posts" :key="index">
      <nuxt-link :to="`/posts/${post.id}`">
        <h1>{{ post.title }}</h1>
      </nuxt-link>
      <div>{{ post.body }}</div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Posts',
  data() {
    return {
      posts: null,
    }
  },
  async mounted() {
    this.posts = (
      await this.$axios.get(`https://jsonplaceholder.typicode.com/posts`)
    ).data
  },
}
</script>

Individual post Live example

<!-- pages/posts/_id/index.vue -->

<template>
  <div v-if="post">
    <h1>{{ post.title }}</h1>
    <div>{{ post.body }}</div>
  </div>
</template>

<script>
export default {
  name: 'Post',
  data() {
    return {
      post: null,
    }
  },
  async mounted() {
    this.post = (
      await this.$axios.get(
        `https://jsonplaceholder.typicode.com/posts/${this.$route.params.id}`
      )
    ).data
  },
}
</script>

If you click the live examples above, you can see Axios is working properly to retrieve data from the jsonplaceholder.typicode.com URLs on the live site.

Now you want to use @nuxtjs/sitemap to generate a sitemap. Everything works great locally with every single one of the following configurations. But when you push to Vercel, no matter what approach you take, the async data always comes back blank and the sitemap won’t generate.

config 1: async routes

full code

// nuxt.config.js

  sitemap: {
    hostname: 'https://testsite.com',
    path: '/sitemap',
    gzip: true,
    defaults: {
      changefreq: 'daily',
      priority: 1
    },
    async routes() {
      try {
        const routes = (await axios.get('https://jsonplaceholder.typicode.com/posts')).data

        return routes.map(p => ({
          url: `/posts/${p.id}`,
          changefreq: 'weekly',
          priority: 0.8
        }))
      } catch (err) {
        console.error(err)
      }
    }
  },

local result: ✅ vercel result: ❌

error:

ERROR  Cannot read property 'map' of null
  at joinRoutes (node_modules/@nuxtjs/sitemap/lib/cache.js:76:31)
  at AsyncCache.load [as _load] (node_modules/@nuxtjs/sitemap/lib/cache.js:19:18)
  at processTicksAndRejections (internal/process/task_queues.js:93:5)

config 2: async nuxt.config.js

full code

// nuxt.config.js

export default async function () {
  try {
    let routes = (await axios.get('https://jsonplaceholder.typicode.com/posts')).data

    routes = routes.map(p => ({
      url: `/posts/${p.id}`,
      changefreq: 'weekly',
      priority: 0.8
    }))

    return {
      [...]
      sitemap: {
        hostname: 'https://testsite.com',
        path: '/sitemap',
        gzip: true,
        defaults: {
          changefreq: 'daily',
          priority: 1
        },
        routes
      },
    [...]
    }
  } catch (err) {
    console.error(err)
  }
}

local result: ✅ vercel result: ❌

error:

 ERROR  Cannot read property 'map' of null
  at joinRoutes (node_modules/@nuxtjs/sitemap/lib/cache.js:76:31)
  at AsyncCache.load [as _load] (node_modules/@nuxtjs/sitemap/lib/cache.js:19:18)
  at processTicksAndRejections (internal/process/task_queues.js:93:5)

config 3: module w/ custom server middleware

full code

// nuxt.config.js

  modules: [
    '~modules/sitemap.js',
    '@nuxtjs/sitemap'
  ],

  sitemap: {
    hostname: 'https://testsite.com',
    path: '/sitemap',
    gzip: true,
    defaults: {
      changefreq: 'daily',
      priority: 1
    },
    routes: []
  },
// modules/sitemap.js

import axios from 'axios'

const sitemap = async () => {
  try {
    const routes = (await axios.get('https://jsonplaceholder.typicode.com/posts')).data

    return routes.map(p => ({
      url: `/posts/${p.id}`,
      changefreq: 'weekly',
      priority: 0.8
    }))
  } catch (err) {
    console.error(err)
  }
}

export default function () {
  const { nuxt } = this

  this.addServerMiddleware({
    async handler(req, res, next) {
      if (req.url === '/sitemap') {
        if (nuxt.server.options.sitemap) nuxt.server.options.sitemap.routes.push(...(await sitemap()))
      }

      next()
    }
  })
}

local result: ✅ vercel result: ❌

error:

 ERROR  Cannot read property 'map' of null
  at joinRoutes (node_modules/@nuxtjs/sitemap/lib/cache.js:76:31)
  at AsyncCache.load [as _load] (node_modules/@nuxtjs/sitemap/lib/cache.js:19:18)

config 4: generate static sitemap w/o middleware

full code

// nuxt.config.js

  sitemap: {
    hostname: 'https://testsite.com',
    path: '/sitemap',
    gzip: true,
    defaults: {
      changefreq: 'daily',
      priority: 1
    },
    generate: true,
    async routes() {
      const routes = (await axios.get('https://jsonplaceholder.typicode.com/posts')).data

      return routes.map(p => ({
        url: `/posts/${p.id}`,
        changefreq: 'weekly',
        priority: 0.8
      }))
    }
  },

local result: ✅ vercel result: ❌

error:

 ERROR  Cannot read property 'map' of null
  at joinRoutes (node_modules/@nuxtjs/sitemap/lib/cache.js:76:31)
  at AsyncCache.load [as _load] (node_modules/@nuxtjs/sitemap/lib/cache.js:19:18)

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:2
  • Comments:8 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
VSKutcommented, Sep 6, 2021

@selfagency, I have a solution: "builds": [ { "src": "nuxt.config.js", "use": "@nuxtjs/vercel-builder", "config": { "serverFiles": [".nuxt/dist/sitemap-routes.json"] } ]

Just add .nuxt/dist/sitemap-routes.json to your vercel.json and it will be work

3reactions
selfagencycommented, Feb 24, 2021

So there are a couple of things I noticed as I continued troubleshooting this yesterday:

The first is that @nuxtjs/sitemaps only works as server middleware when running in dev mode and only works in production when the target is static and the build method is generate. This, of course, builds a static sitemap during Nuxt’s build step, and does not serve middleware, as the only way server middleware works in Nuxt is when the target is server and you build. I do not believe this is how the module is intended to function, but nonetheless, if you use build with the target as server, the sitemap middleware simply does not work at all. In the end, I wound up writing my own server middleware to generate a sitemap.

The other issue I noticed is that if you make the nuxt.config.js export into a function, once pushed to Vercel, server middleware doesn’t load at all, even if you’re running build to server. My other custom server middleware to generate an RSS feed wouldn’t load at all until I switched my config back from a function to a standard Javascript object. Every other aspect of my nuxt.config.js worked just fine, however.

With regards to the network requests on function startup, the initial API request I had in my nuxt.config.js was only made during the build step, which then — as far as I understand — places the resolved environment variables into the generated code. Ergo, it should not have an impact on lambda startup times.

Whatever the case may be, I wound up having to a) not use functions in my nuxt.config.js and b) drop the @nuxtjs/sitemap module all together in order to get my site working properly again. These issues run counter to the documentation for both Nuxt and @nuxtjs/sitemap.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ERROR 500 on axios API Call in Next JS after deployment to ...
I am using a simple API to send Emails via axios and nodemailer in Next JS. Locally everythings works normally, after deployment to...
Read more >
How to Create a Blog Using Next.js and Contentful CMS
Vercel will automatically rebuild your Next.JS website when you push a new commit of your code to Github. I also recommend using the...
Read more >
nextjs cannot set headers after they are sent to the client
Im having this warning in NextJS when trying to delete a product from my Mongo DB. The warning shows but the product is...
Read more >
How to Build a Portfolio Site with Next.js and TailwindCSS
The code is pushed to a remote GitHub repository and with every push, ... import axios from "axios"; const getLatestRepos = async (data) ......
Read more >
sitemap-2.xml - LogRocket Blog
... https://blog.logrocket.com/choosing-right-progress-indicators-async-flutter-apps/ ... https://blog.logrocket.com/handling-data-fetching-next-js-useswr/ ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found