Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions fern/products/docs/pages/changelog/2026-04-23.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
tags: ["seo", "configuration", "docs.yml"]
---

## Redesigned dynamic OG images

Dynamic OG images have a new layout with fine-grained control over the logo variant, text and background colors, and which elements appear (section, description, URL, gradient).

```yaml docs.yml
metadata:
og:dynamic: true
og:background-image: ./images/og-background.png
```

<Button intent="none" outlined rightIcon="arrow-right" href="/learn/docs/seo/setting-seo-metadata#dynamic-og-images">Read the docs</Button>
42 changes: 37 additions & 5 deletions fern/products/docs/pages/seo/metadata.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ The image displayed when your docs are shared on LinkedIn, Slack, Discord, and o
</ParamField>

<ParamField path="metadata.og:image:width" type="number" required={false} toc={true}>
The width of your Open Graph image in pixels.
The width of your Open Graph image in pixels. Only applied when `og:image` is set.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [vale] reported by reviewdog 🐶
[Microsoft.Units] Don't spell out the number in 'in pixels'.

</ParamField>

<ParamField path="metadata.og:image:height" type="number" required={false} toc={true}>
The height of your Open Graph image in pixels.
The height of your Open Graph image in pixels. Only applied when `og:image` is set.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [vale] reported by reviewdog 🐶
[Microsoft.Units] Don't spell out the number in 'in pixels'.

</ParamField>

<ParamField path="metadata.og:logo" type="string" required={false} toc={true}>
Expand All @@ -105,24 +105,56 @@ The image displayed when your docs are shared on LinkedIn, Slack, Discord, and o

### Dynamic OG images <Availability type="beta" /> [#dynamic-og-images]

Instead of using a single static image for all pages, you can enable dynamic OG image generation. When enabled, Fern automatically generates a unique `og:image` for each page that doesn't have one [set in frontmatter](#open-graph).
Instead of using a single static image for all pages, you can enable dynamic OG image generation. When enabled, Fern automatically generates a unique `og:image` for each page that doesn't have one [set in frontmatter](#open-graph). The `og:dynamic:*` sub-settings and `og:background-image` below are only read when `og:dynamic: true` — they are ignored otherwise. `fern check` surfaces warnings for conflicting settings so you can resolve them locally.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [vale] reported by reviewdog 🐶
[Microsoft.Contractions] Use 'they're' instead of 'they are'.


You can optionally provide a custom background image (`og:background-image`) for dynamically generated OG images.

```yaml docs.yml
metadata:
og:dynamic: true
og:background-image: ./images/og-background.png # optional
og:background-image: ./images/og-background.png
```

<ParamField path="metadata.og:dynamic" type="boolean" required={false} default={false} toc={true}>
When `true`, enables dynamic OG image generation for pages that don't have a custom `og:image` set.
When `true`, enables dynamic OG image generation for pages that don't have a custom `og:image` set. Any site-wide `og:image` and `twitter:image` still apply to the homepage; every other page uses the dynamically generated image.
</ParamField>

<ParamField path="metadata.og:background-image" type="string" required={false} toc={true}>
A custom background image for dynamically generated OG images. Can be a URL or a relative file path. Relative paths are resolved from the YAML file where this property is set (e.g., `docs.yml`). When set, this image is used as the background instead of a solid color.
</ParamField>

<ParamField path="metadata.og:dynamic:text-color" type="string" required={false} toc={true}>
Override the text color for dynamically generated OG images. Accepts any valid CSS color value (e.g., `"#1a1a1a"`). By default, Fern auto-detects the text color from your site's theme. Use this when the auto-detected color doesn't contrast well with your background. Must differ from `og:dynamic:background-color` so the text remains visible.
</ParamField>

<ParamField path="metadata.og:dynamic:background-color" type="string" required={false} toc={true}>
Override the background color for dynamically generated OG images. Accepts any valid CSS color value (e.g., `"#ffffff"`). By default, Fern uses your site's theme background color.
</ParamField>

<ParamField path="metadata.og:dynamic:logo-color" type="enum" required={false} default="dark" toc={true}>
Choose which logo variant to render in dynamically generated OG images. Accepts `dark` or `light`, matching the corresponding entry under the top-level [`logo:` setting](/learn/docs/getting-started/global-configuration#logo-configuration) in your `docs.yml`. If your `docs.yml` only defines one logo variant, that variant is used regardless of this setting. Has no effect when `og:dynamic:show-logo: false`.
</ParamField>

<ParamField path="metadata.og:dynamic:show-logo" type="boolean" required={false} default={true} toc={true}>
Toggle visibility of the logo in dynamically generated OG images. Defaults to `true` when `og:dynamic` is enabled.
</ParamField>

<ParamField path="metadata.og:dynamic:show-section" type="boolean" required={false} default={true} toc={true}>
Toggle visibility of the section title in dynamically generated OG images. The section title is derived from the page's navigation breadcrumb. Defaults to `true` when `og:dynamic` is enabled.
</ParamField>

<ParamField path="metadata.og:dynamic:show-description" type="boolean" required={false} default={true} toc={true}>
Toggle visibility of the page description in dynamically generated OG images. The description is extracted from the page's frontmatter (`description`, `subtitle`, or `excerpt`). Defaults to `true` when `og:dynamic` is enabled.
</ParamField>

<ParamField path="metadata.og:dynamic:show-url" type="boolean" required={false} default={true} toc={true}>
Toggle visibility of the page URL in dynamically generated OG images. Defaults to `true` when `og:dynamic` is enabled.
</ParamField>

<ParamField path="metadata.og:dynamic:show-gradient" type="boolean" required={false} default={true} toc={true}>
Toggle visibility of the accent gradient overlay in dynamically generated OG images. The gradient uses your accent color. Defaults to `true` when `og:dynamic` is enabled.
</ParamField>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[FernStyles.Headings] 'Twitter / X' should use sentence-style capitalization.

### Twitter / X

Controls how your docs appear in Twitter Card previews when shared on X.
Expand Down
40 changes: 40 additions & 0 deletions fern/snippets/seo-metadata-site.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ metadata:
# Dynamic OG images (beta)
og:dynamic: true
og:background-image: "https://developer.squareup.com/images/og-background.png"
og:dynamic:text-color: "#1a1a1a"
og:dynamic:background-color: "#ffffff"
og:dynamic:logo-color: dark
og:dynamic:show-logo: true
og:dynamic:show-section: true
og:dynamic:show-description: true
og:dynamic:show-url: true
og:dynamic:show-gradient: true

# Twitter/X
twitter:title: "Square Developer Platform Documentation"
Expand Down Expand Up @@ -95,6 +103,38 @@ metadata:
A custom background image for dynamically generated OG images. Can be a URL or a relative file path. Relative paths are resolved from the YAML file where this property is set (e.g., `docs.yml`).
</ParamField>

<ParamField path="metadata.og:dynamic:text-color" type="string" required={false}>
Override the text color for dynamically generated OG images. Accepts any valid CSS color value. Use this when the auto-detected color doesn't contrast well with your background.
</ParamField>

<ParamField path="metadata.og:dynamic:background-color" type="string" required={false}>
Override the background color for dynamically generated OG images. Accepts any valid CSS color value.
</ParamField>

<ParamField path="metadata.og:dynamic:logo-color" type="enum" required={false}>
Choose which logo variant (`dark` or `light`) to render in dynamically generated OG images. Defaults to `dark`.
</ParamField>

<ParamField path="metadata.og:dynamic:show-logo" type="boolean" required={false}>
Toggle visibility of the logo in dynamically generated OG images. Defaults to `true` when `og:dynamic` is enabled.
</ParamField>

<ParamField path="metadata.og:dynamic:show-section" type="boolean" required={false}>
Toggle visibility of the section title in dynamically generated OG images. Defaults to `true` when `og:dynamic` is enabled.
</ParamField>

<ParamField path="metadata.og:dynamic:show-description" type="boolean" required={false}>
Toggle visibility of the page description in dynamically generated OG images. Defaults to `true` when `og:dynamic` is enabled.
</ParamField>

<ParamField path="metadata.og:dynamic:show-url" type="boolean" required={false}>
Toggle visibility of the page URL in dynamically generated OG images. Defaults to `true` when `og:dynamic` is enabled.
</ParamField>

<ParamField path="metadata.og:dynamic:show-gradient" type="boolean" required={false}>
Toggle visibility of the accent gradient overlay in dynamically generated OG images. Defaults to `true` when `og:dynamic` is enabled.
</ParamField>

<ParamField path="metadata.canonical-host" type="string" required={false}>
The host of your documentation website. This will be used to set the canonical URL for metadata tags and documents like the sitemap.

Expand Down
Loading