diff --git a/README.md b/README.md index 331ef3b..5418e7a 100644 --- a/README.md +++ b/README.md @@ -221,6 +221,15 @@ const nextApiOgImageConfig = { // The hook function return is Map containing custom headers that will be set BEFORE sending // response to the client. hook: null, + // NOTE: Options within 'chrome' object only works when next-api-og-image is run in server (not serverless!!) environment. + chrome: { + // Custom command-line args passed to the browser start command + // by default, no arguments are provided. + args: null, + // Custom executable provided. Useful when you e.g. have to run Chromium instead of Google Chrome + // by default, executable is retrieved automatically (it looks for Google Chrome in the filesystem) + executable: null, + } // NOTE: Options within 'dev' object works only when process.env.NODE_ENV === 'development' dev: { // Whether to replace binary data (image/screenshot) with HTML diff --git a/package-lock.json b/package-lock.json index 92a535f..50df37d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "next-api-og-image", - "version": "4.2.2", + "version": "4.3.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "next-api-og-image", - "version": "4.2.2", + "version": "4.3.0", "license": "MIT", "dependencies": { "deepmerge": "^4.2.2", diff --git a/package.json b/package.json index c1c0895..2295004 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "next-api-og-image", - "version": "4.2.2", + "version": "4.3.0", "description": "Easy way to generate open-graph images dynamically using Next.js API Routes.", "scripts": { "prepublishOnly": "npm run build", diff --git a/src/index.ts b/src/index.ts index 540e8f6..48e8c40 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,6 +29,11 @@ type NextApiRequestWithOgImage = { image: string | Buffer } +type ChromeOptions = { + args?: string[] + executable?: string +} + export type NextApiOgImageConfig< Strategy extends StrategyOption, StrategyDetails extends string | object = string, @@ -47,6 +52,7 @@ export type NextApiOgImageConfig< type?: ImageType quality?: number hook?: (request: NextApiRequestWithOgImage) => Map | Promise> + chrome?: ChromeOptions dev?: Partial<{ inspectHtml: boolean errorsInResponse: boolean @@ -72,6 +78,10 @@ export function withOGImage< type: 'png', quality: 90, hook: null, + chrome: { + args: null, + executable: null, + }, dev: { inspectHtml: true, errorsInResponse: true, @@ -89,6 +99,7 @@ export function withOGImage< hook, height, quality, + chrome: { args, executable }, dev: { inspectHtml, errorsInResponse }, } = options @@ -104,7 +115,7 @@ export function withOGImage< const createBrowserEnvironment = pipe( getChromiumExecutable, - prepareWebPageFactory({ width, height }), + prepareWebPageFactory({ width, height }, { args, executable }), createImageFactory({ inspectHtml, type, quality }), ) @@ -246,7 +257,7 @@ function getChromiumExecutable(browserEnvironment: BrowserEnvironment) { return { ...browserEnvironment, executable } } -function prepareWebPageFactory(viewPort: Viewport) { +function prepareWebPageFactory(viewPort: Viewport, chromeOptions: ChromeOptions) { return async function (browserEnvironment: BrowserEnvironment) { const { page, envMode, executable } = browserEnvironment @@ -254,7 +265,7 @@ function prepareWebPageFactory(viewPort: Viewport) { return { ...browserEnvironment, page } } - const chromiumOptions = await getChromiumOptions(envMode, executable) + const chromiumOptions = await getChromiumOptions(envMode, executable, chromeOptions) const browser = await core.launch(chromiumOptions) const newPage = await browser.newPage() @@ -264,9 +275,17 @@ function prepareWebPageFactory(viewPort: Viewport) { } } -async function getChromiumOptions(envMode: EnvMode, executable: string) { +async function getChromiumOptions( + envMode: EnvMode, + defaultExecutable: string, + chromeOptions?: ChromeOptions, +) { if (!isProductionLikeMode(envMode)) { - return { args: [], executablePath: executable, headless: true } + return { + args: chromeOptions?.args ?? [], + executablePath: chromeOptions?.executable ?? defaultExecutable, + headless: true, + } } else { if (isLambda) { return { @@ -275,7 +294,11 @@ async function getChromiumOptions(envMode: EnvMode, executable: string) { headless: chrome.headless, } } else { - return { args: [], executablePath: executable, headless: true } + return { + args: chromeOptions?.args ?? [], + executablePath: chromeOptions?.executable ?? defaultExecutable, + headless: true, + } } } }