Skip to content
Metadata API · Use case

Fix missing or wrong og:image, title and description

When og:image is missing and there is no fallback, the link preview renders as a gray box. Some pages have no Open Graph image at all. Others put the site name where the title should be, or a tracking pixel where the image should be. The Metadata API lets you override any normalized field with a rule and chain fallbacks until one yields a valid value.

The problem

A page with a missing og:image or a wrong title breaks the card

Microlink already merges Open Graph, Twitter Cards, JSON-LD and the HTML into one shape and picks the best candidate for each field. When a page ships wrong or empty tags, there is nothing better to pick from, and the card your users see has no image or the wrong headline.

Patching it in the UI does not scale: every client needs the same special cases, and the stored metadata stays wrong for search, feeds and emails. Asking the site owner to fix their tags works for your own pages, which you can check with the sharing debugger, but not for the rest of the web.

A data rule named after a normalized field overrides it. Point image at the first real picture in the article, title at the h1, description at the first paragraph, and list several rules so the first one that yields a valid value wins.

How it works

How to override a title or og:image in the metadata API

Name the rule after the field to replace it. Pass an array of rules to try them in order until one matches and passes its type. The extending results guide shows the same data option adding new fields instead.

1 · Override og:image with the article image
import createClient from 'microlink.io'

const microlink = createClient({
  apiKey: process.env.MICROLINK_API_KEY
})

const { title, image } = await microlink.metadata('https://example.com/post', {
  data: {
    image: {
      selector: 'article img',
      attr: 'src',
      type: 'image'
    }
  }
})

The image rule replaces the normalized image. The image type resolves the src to an absolute URL and expands it into an asset object with width, height, type and size.

2 · Fallback chain for the title
import createClient from 'microlink.io'

const microlink = createClient({
  apiKey: process.env.MICROLINK_API_KEY
})

const { title } = await microlink.metadata('https://example.com/post', {
  data: {
    title: [
      { selector: 'meta[property="og:title"]:not([content=""])', attr: 'content' },
      { selector: 'article h1', attr: 'text' },
      { selector: 'title', attr: 'text' }
    ]
  }
})

Rules are evaluated in order, and the first one that matches and passes its type wins. The :not([content=""]) part skips an og:title tag that exists but is empty.

3 · The same request as a URL
curl 'https://api.microlink.io/?url=https%3A%2F%2Fexample.com%2Fpost&data.image.selector=article+img&data.image.attr=src&data.image.type=image'

Override rules flatten to data.image.selector, data.image.attr and data.image.type, so the fix works from a plain URL on the free endpoint.

Parameters used
  • data A rule named after a normalized field, such as title or image, overrides that field.
  • type image, url, date, string and other validators. A value that fails its type resolves to null.
  • selector The first match of a CSS selector. Accepts an array of selectors as fallbacks.
  • prerender Set to true when the correct tags only exist after JavaScript runs. Default auto.
  • ping On by default: every URL in the payload is verified as publicly reachable.

Normalized detection already applies its own fallbacks, so add overrides only for the sites that need them. A small per-domain map of rules is usually enough.

Why it works

Why fix a link preview image at the API, not in the UI

Fixing previews in the UI hides the problem in one client. Fixing the field at the API fixes it for every consumer.

01 · Named overrides
The response shape does not change.
Because the override uses the field’s own name, every consumer keeps reading image, title and description exactly as before. The fix is invisible to the UI, the search index and the email template.

The same mechanism adds custom fields when you need values beyond the normalized set.

02 · Validated fallbacks
An empty tag does not win just because it exists.
Selectors that exclude empty content attributes skip blank tags, and the image type rejects values that are not real images. The chain lands on the first usable candidate, or on null when there is none.

ping, on by default, verifies that every URL in the payload is reachable, so a dead image URL does not reach your card.

03 · Cached fix
The corrected preview is cached like any other.
Once resolved, the response is served from the cache for 24 hours by default. Cache hits do not count against your quota, so the extra rules cost nothing on repeat requests.

When not to: if a page has no image at all, no rule can invent one. Render a placeholder from the title, or use a screenshot of the page as the Open Graph image.

FAQ

Why is og:image missing from the metadata response?

The page probably ships no usable image tag, or the tag points at an unreachable URL that ping filtered out. Add an image rule that targets the article’s real image, or fall back to a screenshot of the page. The metadata troubleshooting guide covers client-rendered and blocked pages, the other two causes.

How do I set an og:image fallback when a page has no metadata image?

Pass a data rule named image as an array: first the og:image tag, then the first image inside the article, each with type image. The first candidate that resolves to a real image wins. If none does, the field is null and you can render a placeholder instead.

How do I override the title the metadata API detected?

Pass a data rule named title with the selector you trust, such as article h1 with attr text. A rule named after a normalized field replaces that field in the response, so your code keeps reading title as before.

Can I define several metadata fallbacks for one field?

Yes. Pass an array of rules for the field. They are evaluated in order and the first one that matches and passes its type wins; if none does, the field is null. The fallback rules reference shows the same form for selector and attr on their own.

Do metadata overrides work for client-rendered pages?

Yes. Add prerender: true and, if needed, waitForSelector so the rules run against the rendered DOM rather than the initial HTML. See metadata from single-page apps for the wait options.
Related use cases

Solve the next problem with the same API

Custom fields alongside metadata

Get prices, ratings, headings or any CSS selector, typed and returned next to the normalized metadata.

Metadata from single-page apps

Render React, Vue or Angular apps in a headless browser, wait for the tags, then read the normalized metadata.

Only the fields you need

Include or exclude normalized fields per request and trim the JSON for faster, lighter metadata calls.

Link previews for bot-protected sites

Unfurl links to sites behind Cloudflare or DataDome by routing the metadata request through the built-in proxy.

Dynamic Open Graph images

Point og:image at an API URL and every share shows a current, cached screenshot of the page.

Markdown with metadata frontmatter

Get each page as Markdown with a YAML frontmatter block: title, author, date, word count and reading time.

Ready for previews that never break?

Override the wrong field, chain the fallbacks, cache the fix. Start on the free tier and repair your first broken preview today.