This is the full developer documentation for Astro Snapshot # Say cheese! > Generate screenshots of your Astro pages automatically at build time with Astro Snapshot. Perfect for creating social images, content previews, dynamic icons, and more! ## Features [Section titled “Features”](#features) Framework agnostic Generate images from any valid Astro page or external site, using whatever front-end framework you want. Not limited to preset layouts or restricted CSS like other solutions. Customizable outputs You have full control over the generated images. Choose between PNG, JPEG, or WebP. Generate multiple images per page with different configurations. Save them anywhere. Flexible configuration Define global defaults and override them per image. Pass through options directly to [Puppeteer](https://pptr.dev/) for precise control of the browser, viewport, and screenshot generation process. TypeScript support Full type safety for all options. Import the `Config` type to catch mistakes in your config before you build. Install the package from [JSR](https://jsr.io/@twocaretcat/astro-snapshot) for use with TypeScript-native runtimes like [Deno](https://deno.com/). ## Use Cases [Section titled “Use Cases”](#use-cases) Social images Use your existing front-end components to generate [Open Graph](https://ogp.me/) images and/or Twitter cards for your blog posts or other content. Content previews Generate screenshots of your website for use in documentation, marketing materials, showcases, etc. Favicons Dynamically generate favicons for your website. # Oh Snap! > This page doesn't exist 😔. Check the URL or try searching for what you're looking for instead. # snapshot > API documentation for the snapshot function. > **snapshot**(`config`): `AstroIntegration` Defined in: [index.ts:83](https://github.com/caret-collective/astro-snapshot/blob/e09da27191828dbffe0198e96f563cc8b32e158d/packages/astro-snapshot/src/index.ts#L83) Creates an Astro integration that captures screenshots of specified pages during the `astro:build:done` lifecycle event. ## Parameters [Section titled “Parameters”](#parameters) ### config [Section titled “config”](#config) [`Config`](/api-reference/interfaces/config/) Integration configuration, including page mappings, defaults, and Puppeteer settings. ## Returns [Section titled “Returns”](#returns) `AstroIntegration` The configured Astro integration. ## Examples [Section titled “Examples”](#examples) ``` // Capture the home page and an about page with shared defaults snapshot({ pages: { '/': [{ outputPath: 'src/assets/home-og.png' }], '/about': [{ outputPath: 'src/assets/about-og.png' }], }, defaults: { width: 1200, height: 630, overwrite: true, }, }); ``` ``` // Capture multiple screenshots of the same page at different sizes snapshot({ pages: { '/': [ { outputPath: 'src/assets/og.png', width: 1200, height: 630 }, { outputPath: 'src/assets/square.png', width: 512, height: 512 }, ], }, }); ``` # Config > API documentation for the Config interface. Defined in: [types.ts:182](https://github.com/caret-collective/astro-snapshot/blob/e09da27191828dbffe0198e96f563cc8b32e158d/packages/astro-snapshot/src/types.ts#L182) Global configuration for the snapshot integration. Defines which pages to capture, default behavior, and Puppeteer launch settings. ## Example [Section titled “Example”](#example) ``` const config: SnapshotIntegrationConfig = { pages: { '/': [{ outputPath: 'src/assets/home-og.png' }], '/about': [{ outputPath: 'src/assets/about-og.png' }], }, defaults: { width: 1200, height: 630, overwrite: true, }, launchOptions: { args: ['--no-sandbox', '--disable-setuid-sandbox'], }, }; ``` ## Properties [Section titled “Properties”](#properties) ### defaults? [Section titled “defaults?”](#defaults) > `optional` **defaults?**: `Omit`<`ScreenshotConfig`, `"outputPath"`> Defined in: [types.ts:213](https://github.com/caret-collective/astro-snapshot/blob/e09da27191828dbffe0198e96f563cc8b32e158d/packages/astro-snapshot/src/types.ts#L213) Default configuration applied to all pages. Can be overridden per page in `pages`. #### Example [Section titled “Example”](#example-1) ``` defaults: { width: 512, height: 512, overwrite: true, } ``` *** ### launchOptions? [Section titled “launchOptions?”](#launchoptions) > `optional` **launchOptions?**: `LaunchOptions` Defined in: [types.ts:225](https://github.com/caret-collective/astro-snapshot/blob/e09da27191828dbffe0198e96f563cc8b32e158d/packages/astro-snapshot/src/types.ts#L225) Options to pass to Puppeteer’s [launch()](https://pptr.dev/api/puppeteer.launchoptions) method. #### Example [Section titled “Example”](#example-2) ``` launchOptions: { args: ['--no-sandbox', '--disable-setuid-sandbox'], } ``` *** ### pages [Section titled “pages”](#pages) > **pages**: `Record`<`string`, `ScreenshotConfig`\[]> Defined in: [types.ts:198](https://github.com/caret-collective/astro-snapshot/blob/e09da27191828dbffe0198e96f563cc8b32e158d/packages/astro-snapshot/src/types.ts#L198) Map of page paths or external URLs to their screenshot configurations. Keys can be: * A local page path (ex. `'/'`, `'/about'`) served via the local build server. * An absolute `http://` or `https://` URL loaded directly without the local server. #### Example [Section titled “Example”](#example-3) ``` pages: { '/': [{ outputPath: 'src/assets/home-og.png' }], 'https://johng.io': [{ outputPath: 'src/assets/external.png', width: 512, height: 512 }], } ``` *** ### port? [Section titled “port?”](#port) > `optional` **port?**: `number` Defined in: [types.ts:237](https://github.com/caret-collective/astro-snapshot/blob/e09da27191828dbffe0198e96f563cc8b32e158d/packages/astro-snapshot/src/types.ts#L237) Port for the local server during build. Used to render pages before screenshot generation. #### Default [Section titled “Default”](#default) ``` 4322 ``` #### Example [Section titled “Example”](#example-4) ``` port: 8080 ``` # astro-snapshot > API documentation for the astro-snapshot project. Astro integration for generating automated page snapshots using Puppeteer. This module provides an integration that runs after the build process, starts a local static file server, and captures screenshots for configured routes using a headless browser. See the [documentation](https://astro-snapshot.johng.io) for more information. ## Example [Section titled “Example”](#example) ``` // astro.config.ts import { defineConfig } from 'astro/config'; import snapshot from '@twocaretcat/astro-snapshot'; export default defineConfig({ integrations: [ snapshot({ pages: { '/': [{ outputPath: 'src/assets/og.png' }], }, }), ], }); ``` ## Interfaces [Section titled “Interfaces”](#interfaces) * [Config](/api-reference/interfaces/config/) ## Functions [Section titled “Functions”](#functions) * [snapshot](/api-reference/functions/snapshot/) # Configuration > Configure Astro Snapshot to generate screenshots of your pages. ## Adding Pages [Section titled “Adding Pages”](#adding-pages) Pass a configuration object to the integration in your `astro.config.*` to set things up. astro.config.ts ``` import { defineConfig } from 'astro/config'; import snapshot from '@twocaretcat/astro-snapshot'; export default defineConfig({ integrations: [ snapshot({ pages: { '/': [ { outputPath: 'public/og/home.png', }, ], '/about': [ { outputPath: 'public/og/about.png', width: 1200, height: 630, }, ], }, }), ], }); ``` The only required property is `pages`, which maps URL paths to an array of screenshot configurations. You can add multiple screenshot configurations for a single page to generate multiple screenshots with different settings. Note Input paths must reference a valid Astro page on your site. If not, you’ll get a screenshot of a 404 page instead 😞. ### Output Paths [Section titled “Output Paths”](#output-paths) Each screenshot configuration requires an `outputPath`. The `outputPath` is resolved relative to your project root, so you can write to any directory: `public/`, `src/assets/` 1, `dist/`, or somewhere else. *1 This has some quirks. See [How it Works](/guide/how-it-works) for more details.* #### Supported Formats [Section titled “Supported Formats”](#supported-formats) The output image format is detected automatically from the file extension in `outputPath`. | Extension | Format | | --------------- | ------ | | `.png` | PNG | | `.jpg`, `.jpeg` | JPEG | | `.webp` | WebP | ## Defaults [Section titled “Defaults”](#defaults) Use the `defaults` option to set shared values across all screenshots, then override them per-image as needed. astro.config.ts ``` import { defineConfig } from 'astro/config'; import snapshot from '@twocaretcat/astro-snapshot'; export default defineConfig({ integrations: [ snapshot({ defaults: { width: 1200, height: 630, overwrite: true, }, pages: { '/': [{ outputPath: 'public/og/home.png' }], '/about': [ { outputPath: 'public/og/about.png', height: 400, // overrides the default of 630 }, ], }, }), ], }); ``` ## What’s Next? [Section titled “What’s Next?”](#whats-next) You’ve got the basics down, now what? The [Recipes](/guide/recipes/multiple-images-per-page) section contains a number of example config files that demonstrate how to use the integration. For real-world examples, check out the [Resources](/resources/demo) section, which contains a demo of the integration and links to some third-party sites that use it that you can reference. If you want to get into the nitty-gritty, you can consult the [API Reference](/api-reference/interfaces/config). For common issues and how to fix them, check out the [Troubleshooting](/guide/troubleshooting) section. If you’re curious about how the integration works, there’s a brief explanation in the [How It Works](/guide/how-it-works) section. # Installation > Install Astro Snapshot using your preferred package manager. Astro Snapshot is available on both [JSR](https://jsr.io/@twocaretcat/astro-snapshot) and [npm](https://www.npmjs.com/package/@twocaretcat/astro-snapshot), so you can choose where you want to install it from. Either way, you get full type support. JSR or npm? **JSR** is a good choice if you’re using TypeScript or Deno. It ships typed, modern ESM code by default with no need for separate type declarations. **npm** may be preferable if you’re using a Node-based project, as `astro` is resolved as a peer dependency which avoids potential version mismatch issues. It also works seamlessly with `astro add`. Some package managers may block Puppeteer’s install scripts If Puppeteer fails to download a browser during installation, refer to the [Troubleshooting](/guide/troubleshooting) page. ## Automatic (with `astro add`) [Section titled “Automatic (with astro add)”](#automatic-with-astro-add) You can use the Astro CLI to install and set up the integration automatically using your preferred package manager. Note `astro add` installs from npm. To use the JSR version, follow the manual installation steps below. * npm ``` npx astro add @twocaretcat/astro-snapshot ``` * pnpm ``` pnpm astro add @twocaretcat/astro-snapshot ``` * yarn ``` yarn astro add @twocaretcat/astro-snapshot ``` * bun ``` bunx astro add @twocaretcat/astro-snapshot ``` * Deno ``` deno run -A astro add @twocaretcat/astro-snapshot ``` * vlt ``` vlt astro add @twocaretcat/astro-snapshot ``` ## Manual [Section titled “Manual”](#manual) If you run into any issues, you can install the package manually instead. ### 1. Install [Section titled “1. Install”](#1-install) First, install the package using your preferred package manager. * npm npm ``` npm install @twocaretcat/astro-snapshot ``` JSR ``` npx jsr add @twocaretcat/astro-snapshot ``` * pnpm npm ``` pnpm add @twocaretcat/astro-snapshot ``` JSR ``` pnpm i jsr:@twocaretcat/astro-snapshot ``` * yarn npm ``` yarn add @twocaretcat/astro-snapshot ``` JSR ``` yarn add jsr:@twocaretcat/astro-snapshot ``` * bun npm ``` bun add @twocaretcat/astro-snapshot ``` JSR ``` bunx jsr add @twocaretcat/astro-snapshot ``` * Deno npm ``` deno add npm:@twocaretcat/astro-snapshot ``` JSR (recommended) ``` deno add jsr:@twocaretcat/astro-snapshot ``` * vlt npm ``` vlt install @twocaretcat/astro-snapshot ``` JSR ``` vlt install jsr:@twocaretcat/astro-snapshot ``` ### 2. Add to Config [Section titled “2. Add to Config”](#2-add-to-config) Then add it to your `astro.config.*`. astro.config.ts ``` import { defineConfig } from 'astro/config'; import snapshot from '@twocaretcat/astro-snapshot'; export default defineConfig({ integrations: [], integrations: [snapshot({ pages: {} })], }); ``` Next, you’ll need to [configure](/guide/getting-started/configuration) some pages to screenshot. # How it Works > Learn how Astro Snapshot works under the hood. Build Cycle Limitation Note that, because this plugin runs ***after*** the build completes, you will not be able to import the generated images into your components or perform any further operations with them in the same build cycle. This is relevant if you want to output images to `src/` and import them in pages to take advantage of Astro’s image optimization. You can, however, use them in the next build, provided they are not overwritten. If you do this, make sure to account for the images not existing the first time you perform a build (i.e. use a placeholder image or catch errors from `import` statements). Here’s a high-level overview of how the integration works: 1. After the Astro configuration has resolved (`astro:config:done`), we validate the integration config and store it for later use 2. Then, once the Astro build completes (`astro:build:done`), we consume the resolved config and: 1. launch a local static file server ([sirv](https://github.com/lukeed/sirv)) to serve the build output (if required) 2. use [Puppeteer](https://pptr.dev) to: 1. launch a headless browser 2. navigate to the pages you configured 3. take screenshots of each one and save them to the filesystem as images # Dynamic Pages > Generate screenshots for a dynamic set of pages such as blog posts using programmatically built config. By building the `pages` config programmatically, you can generate screenshots for a dynamic set of pages such as blog posts. This can be useful if you want to generate social preview images for each page on your site. This example generates an OpenGraph image for each blog post. astro.config.ts ``` import { defineConfig } from 'astro/config'; import snapshot from '@twocaretcat/astro-snapshot'; // Replace with however you fetch your slugs (ex. a glob, a CMS call, etc.) const blogPosts = await getBlogPostSlugs(); const blogPages = Object.fromEntries( blogPosts.map((slug) => [ `/blog/${slug}`, [ { outputPath: `public/og/blog/${slug}.png`, width: 1200, height: 630, }, ], ]), ); export default defineConfig({ integrations: [ snapshot({ pages: { '/': [{ outputPath: 'public/og/home.png' }], '/about': [{ outputPath: 'public/og/about.png' }], ...blogPages, }, }), ], }); ``` # External URLs > Take screenshots of pages on external sites by passing http:// or https:// URLs as page keys. Page keys that start with `http://` or `https://` are treated as external URLs so that you can capture pages outside of your build. Screenshots of third-party sites are especially useful for project showcases or link previews. astro.config.ts ``` import { defineConfig } from 'astro/config'; import snapshot from '@twocaretcat/astro-snapshot'; export default defineConfig({ integrations: [ snapshot({ pages: { 'https://example.com': [ { outputPath: 'src/assets/example.jpg', }, ], }, }), ], }); ``` You can freely mix external URLs and local page paths in the same `pages` map. The local server is only started when at least one local path is present. # Kitchen Sink > See what's possible with Astro Snapshot using the full suite of available options. Here’s a configuration example using every available option. astro.config.ts ``` snapshot({ pages: { '/': [ { outputPath: 'public/og/home.png', width: 1200, // Viewport width in px (default: 1200) height: 630, // Viewport height in px (default: 630) overwrite: true, // Overwrite if file already exists (default: false) // Passed to Puppeteer's page.goto() gotoOptions: { waitUntil: 'networkidle0', timeout: 30000, }, // Passed to Puppeteer's page.screenshot() screenshotOptions: { quality: 95, // JPEG only fullPage: false, clip: { x: 0, y: 0, width: 1200, height: 630, }, }, // Passed to Puppeteer's page.setViewport() setViewportOptions: { deviceScaleFactor: 2, isMobile: false, hasTouch: false, isLandscape: true, }, }, ], }, // Defaults applied to all screenshots (optional) defaults: { width: 1200, height: 630, overwrite: true, gotoOptions: { waitUntil: 'networkidle2', }, setViewportOptions: { deviceScaleFactor: 2, }, }, // Port used for the local static file server (default: 4322) port: 4322, // Passed to Puppeteer's launch() launchOptions: { headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'], // Required in some CI environments }, }), ``` See the [API Reference](/api-reference/interfaces/config) for full documentation of each option, and the [Puppeteer docs](https://pptr.dev/api) for details on the pass-through options. # Multiple Images per Page > Generate social media images for various platforms by taking multiple screenshots per page with different dimensions. Referencing Output Paths in Your Pages If you need to reference image output paths in your pages, define the config in a common place and import it into your pages as needed. The integration doesn’t provide any methods for getting the output paths, so you’ll need to manage that yourself. You can define multiple screenshots to be generated for a single page by setting an array of screenshot configurations for a page in the `pages` object. In this example, we use a shared size map to take multiple screenshots for social media, each with their own output dimensions. astro.config.ts ``` import { defineConfig } from 'astro/config'; import snapshot from '@twocaretcat/astro-snapshot'; const socialSizes = { og: { width: 1200, height: 630 }, // OpenGraph twitter: { width: 1200, height: 600 }, // Twitter / X linkedin: { width: 1200, height: 627 }, // LinkedIn instagram: { width: 1080, height: 1080 }, // Instagram }; export default defineConfig({ integrations: [ snapshot({ pages: { '/': Object.entries(socialSizes).map(([platform, dims]) => ({ outputPath: `public/social/${platform}.png`, ...dims, })), }, }), ], }); ``` # Puppeteer Customization > Capture retina-quality screenshots by passing through options directly to Puppeteer. Astro Snapshot allow you to pass through options directly to Puppeteer for more control over the screenshot generation process. In this example, we use `deviceScaleFactor` to increase the pixel density for sharper images on high-DPI displays. astro.config.ts ``` import { defineConfig } from 'astro/config'; import snapshot from '@twocaretcat/astro-snapshot'; export default defineConfig({ integrations: [ snapshot({ // Apply to all screenshots via defaults defaults: { setViewportOptions: { deviceScaleFactor: 2, }, }, pages: { '/': [{ outputPath: 'public/og/home.png' }], }, }), ], }); ``` There’s several pass-through properties you can set for fine-grained control over the whole process. | Option | Relevant Puppeteer Method | | -------------------- | ----------------------------------------------------------------------------- | | `gotoOptions` | [`page.goto()`](https://pptr.dev/api/puppeteer.page.goto) | | `setViewportOptions` | [`page.setViewport()`](https://pptr.dev/api/puppeteer.page.setviewport) | | `screenshotOptions` | [`page.screenshot()`](https://pptr.dev/api/puppeteer.page.screenshot) | | `launchOptions` | [`puppeteer.launch()`](https://pptr.dev/api/puppeteer.browserlauncher.launch) | # TypeScript > Use the Config type for type-safe configuration. Import the `Config` type to get full type checking and autocompletion for your integration config. astro.config.ts ``` import { defineConfig } from 'astro/config'; import snapshot, { type Config } from '@twocaretcat/astro-snapshot'; const snapshotConfig: Config = { pages: { '/': [ { // Type error: '.bmp' is not a supported format outputPath: 'public/og/home.bmp', }, ], }, }; export default defineConfig({ integrations: [snapshot(snapshotConfig)], }); ``` # Troubleshooting > Solutions to common problems with Astro Snapshot. Here’s some common issues and their solutions. If your problem isn’t listed here, [open an issue on GitHub](https://github.com/caret-collective/astro-snapshot/issues) and I’ll see if I can help. ## Puppeteer can’t download a browser during installation [Section titled “Puppeteer can’t download a browser during installation”](#puppeteer-cant-download-a-browser-during-installation) Some package managers block post-install scripts (for example, when using `--ignore-scripts` or in strict CI environments). When this happens, Puppeteer will skip downloading a browser and the integration won’t be able to launch one during snapshot generation. To resolve this, configure your package manager to allow install scripts, install a compatible Chromium or Chrome binary manually, or configure Puppeteer to use an existing browser. You can point to a custom binary using the `PUPPETEER_EXECUTABLE_PATH` environment variable or the `launchOptions.executablePath` option. ## Browser fails to launch in CI due to Linux sandbox restrictions [Section titled “Browser fails to launch in CI due to Linux sandbox restrictions”](#browser-fails-to-launch-in-ci-due-to-linux-sandbox-restrictions) In many container-based CI environments, the Linux sandbox required by Chromium is unavailable. Puppeteer may fail to start with messages such as `No usable sandbox!`. To fix this, refer to Puppeteer’s instructions on how to [configure a sandbox for Chrome on Linux](https://pptr.dev/troubleshooting#setting-up-chrome-linux-sandbox), or run your build inside a base image that includes proper sandbox support, such as the official Chrome/Chromium Docker images. Danger The sandbox exists to prevent malicious websites from gaining elevated privileges on your system, so disabling it is not recommended for production environments. Alternatively, you can disable the sandbox entirely using additional Chromium flags: astro.config.ts ``` import { defineConfig } from 'astro/config'; import snapshot from '@twocaretcat/astro-snapshot'; export default defineConfig({ integrations: [ snapshot({ launchOptions: { args: ['--no-sandbox', '--disable-setuid-sandbox'], }, pages: { // ... }, }), ], }); ``` ## Screenshots appear blank or missing styles [Section titled “Screenshots appear blank or missing styles”](#screenshots-appear-blank-or-missing-styles) This usually occurs when resources haven’t finished loading before the screenshot is taken. You can adjust `gotoOptions.waitUntil` to `networkidle2`, `networkidle0`, or `load`, or increase the timeout to give the page more time to fully render: astro.config.ts ``` import { defineConfig } from 'astro/config'; import snapshot from '@twocaretcat/astro-snapshot'; export default defineConfig({ integrations: [ snapshot({ pages: { '/dashboard': [ { outputPath: 'public/og/dashboard.png', gotoOptions: { waitUntil: 'networkidle0', timeout: 60000, }, }, ], }, }), ], }); ``` ## Routes return 404 or do not match expected paths [Section titled “Routes return 404 or do not match expected paths”](#routes-return-404-or-do-not-match-expected-paths) If the local server can’t serve a configured route, the screenshot will fail or capture an error page. Double-check that your configured paths align with the final build output. ## Output files are not written or directories are missing [Section titled “Output files are not written or directories are missing”](#output-files-are-not-written-or-directories-are-missing) While the integration creates necessary directories automatically, certain environments, especially CI filesystems, may impose write restrictions that prevent screenshots from being saved. Verify that the target directory is writable and not mounted as read-only. ## Build fails with `Astro found issue(s) with your configuration` [Section titled “Build fails with Astro found issue(s) with your configuration”](#build-fails-with-astro-found-issues-with-your-configuration) Note [This issue](https://github.com/caret-collective/astro-snapshot/issues/26) was fixed in [**v2.2.0**](/changelog/version/v2-2-0). If you’re on [v2.1.0](/changelog/version/v2-1-0) or lower, upgrade to resolve it. When updating Astro in your project, the version used by the integration may fall behind — particularly when installing from JSR, where `astro` is bundled as a direct dependency rather than a peer dependency. If the two versions differ, the integration’s copy of Astro may fail to validate your config against its older schema, producing an error like: \> astro build ``` [config] Astro found issue(s) with your configuration: ! experimental: Invalid or outdated experimental feature. ``` This tends to surface when your config uses experimental flags or other options introduced in a newer version of Astro than the one the integration was published against. To fix this, make sure the version of Astro in your project matches the version of Astro used by the integration. Usually, you can force the same version to be downloaded by just deleting your `node_modules` and lockfile, then reinstalling your dependencies. # Demo > See Astro Snapshot in action with this demo! Here’s a screenshot of this page captured with Astro Snapshot: ![Screenshot of the Astro Snapshot Demo Page](/_astro/demo.BvsD-piK_1C2sqv.webp "Screenshot of the Astro Snapshot demo page") Snapception! How cool is that? Here’s a screenshot of an external site: ![Screenshot of johng.io/funding](/_astro/demo-external.DzpFoMe8_gsfRR.webp "Screenshot of johng.io/funding") ## Code [Section titled “Code”](#code) Note `overwrite` is disabled in this case because the screenshots already exist and we don’t need to generate them on every build. If you want to get the same effect we are showing here, you’ll need to set `overwrite: true` in your config and run the build a couple times. Here’s the config used to set this up: astro.config.ts ``` import starlight from '@astrojs/starlight'; import { defineConfig } from 'astro/config'; import starlightChangelogs, { makeChangelogsSidebarLinks } from 'starlight-changelogs'; import starlightContextualMenu from 'starlight-contextual-menu'; import starlightLinksValidator from 'starlight-links-validator'; import starlightLlmsTxt from 'starlight-llms-txt'; import starlightMarkdown from 'starlight-markdown'; import starlightSidebarTopics from 'starlight-sidebar-topics'; import starlightThemeNova from 'starlight-theme-nova'; import starlightTypedoc from 'starlight-typedoc'; import snapshot from '../../packages/astro-snapshot/src/index.ts'; // https://astro.build/config export default defineConfig({ site: 'https://astro-snapshot.johng.io', integrations: [ snapshot({ pages: { '/resources/demo': [ { outputPath: `src/assets/demo.png`, width: 1280, height: 720, overwrite: false, }, ], 'https://johng.io/funding': [ { outputPath: `src/assets/demo-external.png`, width: 1280, height: 720, overwrite: false, }, ], }, }), starlight({ title: 'Astro Snapshot', // This has to be relative to the public/ dir :( favicon: '/icon.svg', logo: { src: '../icon.svg', }, lastUpdated: true, credits: true, social: [ { icon: 'github', label: 'GitHub', href: 'https://github.com/caret-collective/astro-snapshot', }, { icon: 'jsr', label: 'JSR', href: 'https://jsr.io/@twocaretcat/astro-snapshot', }, { icon: 'npm', label: 'npm', href: 'https://www.npmjs.com/package/@twocaretcat/astro-snapshot', }, ], components: { Footer: './src/components/Footer.astro', }, plugins: [ starlightTypedoc({ entryPoints: ['../../packages/astro-snapshot/src/index.ts'], tsconfig: '../../packages/astro-snapshot/tsconfig.json', output: 'api-reference', typeDoc: { name: 'astro-snapshot', plugin: [ 'typedoc-plugin-rename-defaults', 'typedoc-plugin-frontmatter', './src/plugins/frontmatter.ts', ], }, }), starlightChangelogs(), starlightMarkdown(), starlightThemeNova(), starlightLlmsTxt(), starlightContextualMenu({ actions: ['copy', 'view', 'chatgpt', 'claude'], injectMarkdownRoutes: false, }), starlightSidebarTopics([ { label: 'Guide', link: '/guide/getting-started/installation', icon: 'open-book', // It would be epic if we could generate this recursively, but when we do this, lowercase folder names are used // We could use `starlight-auto-sidebar` to rename sidebar groups, but this seems to be incompatible with `starlight-sidebar-topics` :( items: [ { label: 'Guide', items: [ { label: 'Getting Started', items: [{ autogenerate: { directory: 'guide/getting-started' } }], }, { label: 'Recipes', items: [{ autogenerate: { directory: 'guide/recipes' } }], }, { label: 'Troubleshooting', slug: 'guide/troubleshooting', }, { label: 'How it Works', slug: 'guide/how-it-works', }, ], }, ], }, { id: 'api-reference', label: 'API Reference', link: '/api-reference/readme', icon: 'seti:json', // Sidebar groups are lowercase. Ideally we would use `typeDocSidebarGroup` from `starlight-typedoc` here, but it seems to be incompatible with `starlight-sidebar-topics` :( items: [ { label: 'API Reference', items: [{ autogenerate: { directory: 'api-reference' } }], }, ], }, { id: 'changelog', label: 'Changelog', link: '/changelog', icon: 'list-format', items: [ { label: 'Changelog', items: [ ...makeChangelogsSidebarLinks([ { type: 'all', base: 'changelog', label: 'Overview', }, ]), { label: 'Versions', items: [ ...makeChangelogsSidebarLinks([ { type: 'recent', base: 'changelog', count: 10, }, ]), ], }, ], }, ], }, { label: 'Resources', link: '/resources/demo', icon: 'seti:svg', items: [ { label: 'Resources', items: [{ autogenerate: { directory: 'resources' } }], }, ], }, ], { topics: { changelog: ['/changelog/**/*'], 'api-reference': ['/api-reference/**/*'], }, }), starlightLinksValidator({ exclude: [ '/changelog{,/**/*}', ], }), ], customCss: [ '@fontsource/dela-gothic-one', './src/styles/global.css', ], editLink: { baseUrl: 'https://github.com/caret-collective/astro-snapshot/edit/main/docs/site', }, }), ], }); ``` For a complete example, check out the [source code](https://github.com/caret-collective/astro-snapshot/tree/main/docs/site) for these docs. # Related Projects > A collection of similar projects you might be interested in. This integration was inspired by [astro-selfie](https://github.com/vadimdemedes/astro-selfie) and a similar plugin I wrote for [Gatsby](https://www.gatsbyjs.com/) called [Gatsby Plugin: Component to Image](https://github.com/caret-collective/gatsby-plugin-component-to-image). Compared to astro-selfie, this integration exposes a lot more configuration options which allow you to completely customize how images are generated. ### Suggested [Section titled “Suggested”](#suggested) Similar projects you might like. [Gatsby Plugin: Component to Image](https://github.com/caret-collective/gatsby-plugin-component-to-image)A similar image generation plugin I wrote for the Gatsby framework. ### Alternatives [Section titled “Alternatives”](#alternatives) Competing projects you might want to use instead. [astro-selfie](https://astro.build/integrations/?search=astro-snapshot)A similar integration that automatically generates images for every page. # Showcase > A collection of community made projects and articles featuring Astro Snapshot. Tip If you have a project you’d like to share or a blog post featuring Astro Snapshot, feel free to [open a PR](https://github.com/caret-collective/astro-snapshot/pulls) and add it! ## Projects [Section titled “Projects”](#projects) A collection of community made projects that use Astro Snapshot. [Tally](https://tally.johng.io)Tally uses this integration to generate social images in multiple languages and aspect ratios. ## Mentions [Section titled “Mentions”](#mentions) Times Astro Snapshot has been mentioned on the web. [Astro Integrations Library](https://astro.build/integrations/?search=astro-snapshot) [Astro Blog](https://astro.build/blog/whats-new-november-2025)Astro Snapshot was listed in the November 2025 edition of the “What's new in Astro” article on the Astro Blog. [Astro Newsletter](https://buttondown.com/withastro/archive/the-astro-post-november-2025/)Astro Snapshot was featured in the “Top Ten List” in the November 2025 edition of The Astro Post.