Loading…
Guide
You paste a URL into a submission form and a form full of fields populates itself. That is not magic and it is not a model reading your marketing. It is a scraper fetching your HTML and pulling specific tags out of it in a specific order — and when the tag it wants is not there, it takes the next thing down the list.
Which is why listings come out wrong in such recognisable ways: a title that says Home, a description that is the first link in your nav, a card with a grey rectangle where the screenshot should be. Every one of those is a missing tag, and every one of them is fixable in about ten minutes. This guide is the fallback chain, what breaks at each step, and how to check it before you submit anywhere.
Directories do not agree on much, but the reading order is close to universal, because it is the same order social platforms established for link previews. For each field, the scraper takes the first source that exists and stops.
First og:title. If that is absent, the contents of the <title> element. If that is absent or empty, some scrapers fall back to the first heading or the first substantial line of text on the page — and this is where the guesswork starts, because what counts as the first substantial line differs from one implementation to the next.
First og:description. Then <meta name="description">. Then, again, whatever text the scraper finds first in the body. If your header is markup-first — a logo, a nav, then the hero — the text it finds first may well be a nav item.
First og:image. Some scrapers then try twitter:image, and some fall back to the largest image they can find in the document, though plenty do not bother and simply render an empty card. There is no shared standard for that last step, so treat anything past og:image as luck.
The consequence is worth stating flatly: the fields you did not fill in are not left blank. They are filled in with something worse. A missing tag is not a neutral omission — it is a decision handed to a parser that has no idea what your product does.
The one-line version
Open Graph tags are the only part of this you control precisely. Everything below them in the chain is a fallback whose behaviour varies per directory, and you cannot test all of them. Write the tags and the chain never runs.
The Home listing is the most common failure and it has a boring cause: a template. Site builders, CMS themes and framework starters ship a per-page title that is literally the page name, and the homepage’s page name is “Home”. Nobody looks at it, because a browser tab is small and the favicon is what people use to find the tab anyway. The directory looks at it, and prints it at twenty pixels in a card.
The nav-link description has a similarly dull explanation. With no og:description and no meta description, a scraper that falls back to body text starts reading at the top of the document, and the top of most documents is a skip link, a logo alt text, and a row of nav labels. “Features Pricing Docs Log in” is a real thing to have on your card, and it is the same failure as Home, one tag further down.
Plenty of sites do have a title, and it reads Acme – The #1 AI-Powered Platform for Modern Teams | Acme Inc.. In a search result that is a keyword play. In a directory row, truncated, it becomes “Acme – The #1 AI-Powered Platfo…” and says nothing at all. The tags exist, so nothing looks broken, and the listing is still useless.
This is the real argument for setting og:title separately rather than letting it inherit: the two are read in different places by different things, and they do not want the same sentence. A search title can carry a brand suffix and a keyword. A card title has room for your name and roughly four words about what you do.
The scraper reads the URL you gave it, not your site. Submit a deep link to a blog post, a pricing page or a docs page and it will faithfully describe that page. If your homepage has good tags and your/pricing does not, submitting the latter gets you the worse listing, and no amount of homepage work will change it.
Of the three fields, the image is the one that fails most often and the one you are least likely to notice, because it fails silently. There is no error. The card simply comes out grey.
A relative path in og:image produces no image on most scrapers. This is the single most common cause. It is easy to ship, because a relative path works perfectly in every other context you would test — the browser resolves it against the current document without complaint — and the scraper, which may be resolving the tag out of a stored copy of the HTML rather than in a page context, does not. Write the full URL including the scheme and host.
1200×630 is the size to target. Below that, cards get upscaled into mush or downgraded to a small square thumbnail, depending on the consumer. A 400-pixel-wide logo in the og:image slot is technically valid and looks like a mistake in every card that renders it.
The scraper arrives with no session. If your image lives behind an asset host that requires a signed cookie, a referrer check, a geo-restriction or an authenticated CDN path, it gets nothing. The same applies to images served only to logged-in users on a staging domain, and to any image behind the CDN bot protection that also blocks crawlers — the same class of edge failure covered in the AI-readable site guide.
The check is trivial and almost nobody does it: copy the exact URL out of your og:image tag, open a private window, paste it, and confirm an image appears. Private window, because your own session is exactly the thing the scraper does not have.
curl -sI "https://yourdomain.com/og.png" | head -n 1 # want: HTTP/2 200 # a 302 to a login page, a 403, or a 404 all render as an empty card
Dynamically generated Open Graph images are fine and often better than a static file, but they add a failure mode: if the generator is a serverless function that cold-starts slowly, a scraper on a short timeout may give up before it responds. If you use one, fetch it cold a few times and watch how long it takes. A cached static PNG has no such problem, and for most products the card does not need to be dynamic.
Many directory scrapers execute no JavaScript. They fetch the HTML, parse it, and stop — exactly like the crawlers behind the AI assistants. This is the failure that produces the most confusing bug reports, because the page is visibly, obviously fine in a browser.
If your meta tags are injected client-side — by a router, a head manager that only runs after hydration, or an analytics-style script that sets them on load — then the document the scraper receives has either no tags at all or the generic defaults from your HTML shell. A client-rendered marketing page can look immaculate to you and arrive at the directory as an empty shell with a placeholder title.
The same applies to the visible text. If a scraper falls through to body text and your body is a single empty root element, there is no body text to fall through to. That is how a listing ends up with a title, no description, and no image, from a site that has all three on screen.
You can measure this directly. The tool on this site fetches your page with JavaScript disabled and shows you the raw text that comes back — built for the AI crawlers, but the mechanism is identical, so the answer transfers.
Or do it by hand, which takes one command and is worth doing at least once so you believe the result:
curl -sS https://yourdomain.com/ | grep -i 'og:\|<title\|name="description"'
What that prints is what a directory has to work with. Not what devtools shows you — devtools shows the DOM after JavaScript has run, which is a different document. View-source and curl show the delivered HTML, and the delivered HTML is the whole story.
Listing rows are usually a small square, a name, and a line of text. The small square is your favicon. If you do not have one, or the one you have does not resolve at the path the directory looked for, the row renders a blank square.
It is a small thing that reads badly out of proportion to its size. In a list of thirty products where twenty-nine have an icon, the blank one looks abandoned — like a project whose domain lapsed. Nobody consciously thinks that; they just do not click.
Ship a real favicon file, at a real path, reachable without authentication, and confirm it loads in a private window the same way you confirmed the og:image. This is five minutes of work that you do once, and it applies to every directory, every browser tab and every bookmark bar for the life of the product.
Most directories truncate titles somewhere around 60 characters and descriptions around 160. Those are the conventional limits, inherited from search result rendering, and the individual cutoffs vary by site — some are shorter, some wrap instead of clipping. Treat them as a budget rather than a rule: write to fit and the variation stops mattering.
The practical discipline is front-loading. Whatever gets cut is cut from the end, so the first forty characters of your title and the first hundred of your description carry the whole message. If your product name and your category are not in that opening, a truncated listing tells a reader nothing they can act on.
<title> if you want it for search, and leave it out of og:title, where it is repeated next to the name anyway.Consistency is the other half of it. Using the same one-line description on your own site, in your directory listings and anywhere else you appear costs nothing and means people encountering you twice recognise you the second time. We are not going to dress that up as a ranking or citation mechanism — it is not one, and anyone telling you a listing buys you AI citations is guessing. It is just cheaper to be described the same way everywhere than differently.
Here is a head that produces a bad listing. Nothing about it is exotic; this is roughly what a default template emits.
<head> <title>Home</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta property="og:image" content="/images/hero.png"> </head>
Read it the way the scraper does. og:title is missing, so it takes <title> and the listing is called Home. There is no og:description and no meta description, so it falls through to body text and prints your nav. og:image is a relative path, so on most scrapers it resolves to nothing and the card is empty. Three failures, all from things that were never filled in rather than things that were filled in wrongly.
The same page, with the chain never allowed to run:
<head> <title>Fernrun — uptime monitoring for solo developers</title> <meta name="description" content="Fernrun pings your endpoints every 30 seconds and texts you when one stops answering. No dashboard to learn, no per-seat pricing, free under ten checks."> <meta property="og:title" content="Fernrun — uptime monitoring for solo developers"> <meta property="og:description" content="Pings your endpoints every 30 seconds and texts you when one stops answering. Free under ten checks."> <meta property="og:image" content="https://fernrun.com/og/cover.png"> <meta property="og:url" content="https://fernrun.com/"> <meta property="og:type" content="website"> <link rel="icon" href="/favicon.ico" sizes="any"> <link rel="icon" href="/icon.svg" type="image/svg+xml"> </head>
Note what changed and what did not. The <title> and og:title are the same here because the name plus the category already fits the budget — when they differ, it is usually the search title carrying an extra keyword or a brand suffix. The meta description runs longer than the og:description on purpose: the first has more room in a search result, the second is going into a card and is written to survive a 160-character cut.
The image is absolute, on the product’s own domain, at a path that serves a 1200×630 PNG to anyone who asks. The favicon is declared twice, which is ordinary practice for covering both older consumers and modern ones. None of this is clever. It is a checklist, and it takes longer to read about than to do.
Frameworks
If you are on a framework with a metadata API, set these through it rather than hand-writing tags into a layout, and make sure the value you pass for the image is an absolute URL or that the framework is configured with a base URL that makes it one. The output is what matters — check it with curl afterwards either way.
It is worth being precise about which parts of this you can verify and which are inference, because a lot of advice in this area is stated with more confidence than it has earned.
Whether the tags are in your delivered HTML. Whether og:image is an absolute URL. What status code that image URL returns to a request with no cookies. What your favicon path returns. Whether your content is present without JavaScript. All of these are settled with curl or a private browser window, and none of them requires trusting anybody’s claim.
The 60 and 160-character cutoffs are the common convention, not a specification — individual sites clip at different points or wrap instead. The 1200×630 target is the widely used card size, and a given directory may crop it differently. What a scraper does after og:image fails varies: some try twitter:image, some look for the largest image on the page, some give up. Write to the convention and the variation stops being your problem.
Whether a better card gets you more clicks in a given directory. We have not measured it and we are not going to assert a number. It is reasonable to think a listing with a title, a sentence and an image outperforms one that says Home next to a grey rectangle, but reasonable is not measured.
Whether any of this affects search rankings or whether an assistant mentions you. There is no evidence that a directory listing causes either, and we run a directory, so read that with the scepticism it deserves — and note which way our interest points. The honest case for fixing your tags is narrower and sturdier: it decides what your listing says about you, on every site that scrapes you, forever, and it costs ten minutes.
In this order, because each step is pointless if the one before it fails.
Once that passes, submitting is the easy part. Our own submission form reads your page the way described above and shows you what it found before anything is published, so a bad card is visible at the point you can still fix it rather than after it is live. Everything you correct for one directory is correct for all of them, which is the nice property of working on the source rather than on the listing.
LetsLaunch makes money when people list products here, so treat anything we say about directories with the scepticism it deserves — including the list on our directories page. The checks above do not require you to trust us: every one of them is a curl command or a private browser window.