So you want to show a website preview.
Your first thought,
I'll just stick the URL in an iframe and be done with it
You try that and realise some, if not most websites block embedding via iframe. And that might not be the best option because you'll have a fully running website embedded.
You say OK, lets' try using Node.js to launch a browser and take a screenshot of the website. You install playwright.
npm install playwright
Everything in this article applies to puppeteer with some minor code changes.
You Launch the browser
import playwright from "playwright";
const browser = await playwright.chromium.launch({
headless: true
});
const page = await browser.newPage();
await page.goto(url, { waitUntil: "networkidle" });
const screenshot = await page.screenshot();
await browser.close();
take the screenshot and it all works fine on your local machine
it works on my machine 😅
Then you deploy to production and realise that for some reason the post install script of playwright to install the browser (chromium) binary didn't run (depending on your environment and package manager). You stick a postinstall
script in your package.json
and everything seems to work fine.
{
"scripts": {
"postinstall": "npx playwright install",
}
}
Then you try to launch the browser in production and get hit with a wall of
browserType.launch: Executable doesn't exist at /home/sbx_user1051/.cache/ms-playwright/chromium-1084/chrome-linux/chrome
╔═════════════════════════════════════════════════════════════════════════╗
║ Looks like Playwright Test or Playwright was just installed or updated. ║
║ Please run the following command to download new browsers: ║
║ ║
║ npx playwright install ║
║ ║
║ <3 Playwright Team ║
╚═════════════════════════════════════════════════════════════════════════╝
Tested on Vercel edge function and cloudflare pages.
After hours of countless Google searches and Github issues trying to figure out why playwright can't find the install browser binary, you find @sparticuz/chromium
.
You install it
npm install @sparticuz/chromium playwright-core
locate the executable path in production and everything at long last works perfectly.
import chromium from "@sparticuz/chromium";
import playwright from "playwright-core";
const executablePath = await chromium.executablePath()
const browser = await playwright.chromium.launch({
executablePath,
headless: true, // use this instead of using chromium.headless because it uses the new `headless: "new"` which will throw because playwright expects `headless: boolean`
args: chromium.args
})
// ...
And you go on to make millions.
Something seemingly as straight forward as display a website preview ends up being complicated. However, with each challenge, we found solutions – sometimes in unexpected places.
May your deploys be smooth, your error messages be clear, and your code always run in production as it did on your machine. Happy coding! 😄🚀