Aman
Aman

Reputation: 417

Gatsby: Puppeteer Causes TimeoutError: Navigation timeout of 30000 ms exceeded

I'm trying to generate images for each of my Gatsby posts when I run gatsby build using puppeteer. I have included the following script in my puppet.js:

const puppeteer = require('puppeteer')

const baseUrl = process.argv[2] || 'http://localhost:8000/'
const takeScreenshot = async (slug) => {
    const browser = await puppeteer.launch({
        args: ['--no-sandbox', '--disable-setuid-sandbox'],
    })
    let url = `${baseUrl}/${slug}/thumbnail`
    let destination = `/static/posts/${slug}-share.png`
    let width = 440
    let height = 220
    const page = await browser.newPage()
    await page.goto(url, {
        waitUntil: 'networkidle2',
    })
    await page.screenshot({
        path: destination,
        clip: {
            x: 0,
            y: 0,
            width,
            height,
        },
    })

    await browser.close()
    res.status(200).send("ok");


}


const main = async (file) => {
    const destinationFile = `/static/posts/${file}-share.png`

    await takeScreenshot(file)
    console.log(`Created ${file}`)


}

function generateImage(slug) {

    const file = slug
    main(file)
}

module.exports.generateImage = generateImage

I call it in my gatsby-node.js like so:

var image = require('./src/utils/puppet')

And execute it like so:

const toolNodes = data.portfolio.nodes;
let slugs = [];
toolNodes.map(toolNode => slugs.push(toolNode.slug));  

console.log(slugs)
slugs.forEach(node => {
   image.generateImage(node) 
 })

Above, I make an array of slug values and run the function generateImage for each of them. In theory, this value should be passed to the puppet.js file which should then use it to navigate to the correct url, take a screenshot and save the file.

Instead of working, I get this:

Navigation timeout of 30000 ms exceeded
TimeoutError: Navigation timeout of 30000 ms exceeded

How can I fix this? Currently, I do not see any output of images in my directories.

Additionally, is this way to go about it a bad idea? Should this script be in my gatsby-node.js at all? If not, where do I run this from?

For additional context, this is my gatsby-node.js file

Upvotes: 1

Views: 493

Answers (1)

coreyward
coreyward

Reputation: 80051

There are a number of issues with this.

  1. During gatsby build, the Gatsby development server is not running, so localhost:8000 is not likely to be serving your website for Puppeteer to crawl
  2. The createPages function is called earlier in the booting process for gatsby develop than the Express server binding, so at the time this code runs in development localhost:8000 will similarly not be available
  3. takeScreenshot is async, but you're not waiting for it to finish before calling resolve on the Promise being returned by createPages, so Gatsby isn't waiting for them to finish

You might consider instead using onPostBuild to generate these images if you are able to predetermine the path for any references to them. You would still need to run a server to get the pages to be available to Puppeteer (e.g. with Express), though, and this might get tricky since you haven't finished the build.

Upvotes: 1

Related Questions