Last active
March 11, 2024 02:54
-
-
Save dantldev/a7e417688c3e59ce01fb4e78a76b709a to your computer and use it in GitHub Desktop.
A workaround to get screenshots from a url on nextjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This is an api file. | |
* You will need import 'puppeteer' on local env and 'puppeteer-core' on production env. | |
* for that, you can import both in a file and export based on process.env.NODE_ENV like this: | |
* | |
import puppeteerProd from 'puppeteer-core'; | |
import puppeteerDev from 'puppeteer'; | |
export default process.env.NODE_ENV === 'production' | |
? puppeteerProd | |
: puppeteerDev; | |
*/ | |
import { _handleError } from '../../utils/utils'; | |
import puppeteer from '../../utils/puppeteer'; | |
import chrome from 'chrome-aws-lambda'; | |
export default async (req, res) => { | |
try { | |
const browser = await puppeteer.launch( | |
process.env.NODE_ENV === 'production' | |
? { | |
args: chrome.args, | |
executablePath: await chrome.executablePath, | |
headless: chrome.headless, | |
} | |
: {}, | |
); | |
const page = await browser.newPage(); | |
page.setUserAgent( | |
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:86.0) Gecko/20100101 Firefox/86.0', | |
); | |
await page.setViewport({ | |
width: 1920, | |
height: 1080, | |
}); | |
await page.goto(req.query.url || 'https://amazon.com'); | |
const screenshot = await page.screenshot({ | |
encoding: 'base64', | |
}); | |
await browser.close(); | |
res.json({ blob: `data:image/jpeg;base64,${screenshot}` }); | |
} catch (error) { | |
console.log(error); | |
_handleError(res); | |
} | |
}; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import puppeteerProd from 'puppeteer-core'; | |
import puppeteerDev from 'puppeteer'; | |
export default process.env.NODE_ENV === 'production' | |
? puppeteerProd | |
: puppeteerDev; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* you can call the api route with fetch and will return the base64 blob as json. | |
* you can use it on a <img /> tag like so: | |
*/ | |
import { useEffect, useState } from 'react'; | |
export const WebScreenshot = ({ url }) => { | |
const [data, setData] = useState(null); | |
useEffect(() => { | |
fetch(`/api/get-screenshot${url ? `?url=${url}` : ''}`) | |
.then((res) => res.json()) | |
.then((res) => setData(res.blob)) | |
.catch((err) => console.log(err)); | |
}, []); | |
return ( | |
<div> | |
{!data ? <p>Loading...</p> : <img src={data} />} | |
</div> | |
); | |
}; |
@lccarrier you won't be able to deploy this on Vercel. Recently, Vercel reduced their runtime limits down to 10s. The right way to do it is to pick chromium according to environment. For free tier servers, fetch a prebuilt tar file of chromium at runtime which can help bypass bundle size limits of most servers.
Here's how i did it in my recent project: https://github.com/realityzero/ScrapifyX/blob/main/app/utils/puppeteer.ts
@lccarrier @realityzero hi, this gist is from Apr 3, 2021. Lot of things has changed since then. It doesn't work anymore
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ftdgomez were you able to deploy this on Vercel?
My attempt doesn't build, error says the function is too large.