Which meta tags actually change something
A modern page needs far fewer meta tags than the copy-paste lists suggest. The ones that do something are: title, meta description, link rel=canonical, meta robots, meta viewport, meta charset, the html lang attribute, and the Open Graph set. Everything else in a typical "SEO meta tags" list is either ignored or decorative.
meta keywords is the clearest example. Google stopped using it in 2009 and says so explicitly; the only lasting effect of shipping it is that anyone can read your keyword list in view-source. meta revisit-after, meta rating, meta distribution and meta generator have no consumer either.
Two tags are excluded from this generator on purpose: charset and viewport. Both belong at the very top of your document — charset within the first 1024 bytes of the head — and both are usually written once in a layout template, not per page.
- Values are escaped for you. If your title contains & or a quotation mark, the generated code shows & and " — paste it as it is and do not escape it again.
Open Graph: four required tags and one that decides everything
The Open Graph protocol declares four required properties: og:title, og:type, og:image and og:url. In practice a card renders with fewer, because every platform has fallbacks — og:title falls back to <title>, og:url falls back to the address that was shared. The one that has no fallback is og:image.
og:url should carry the canonical address, not the address the visitor happened to use. When a page is shared as ?utm_source=twitter and again with a trailing slash, platforms that see a consistent og:url merge the engagement counts onto one page; without it the counts split. This is why the tool warns when og:url and your canonical differ.
og:type changes how some platforms label the card and which extra properties are allowed. Use website for pages and landing pages, article for posts (which unlocks article:published_time, article:modified_time and article:author), product for a product page, profile for a person. Unknown values are treated as website rather than rejected.
og:site_name is not required but it is what Slack and Discord print above the title. Without it they show the bare domain, which is the difference between "NumLM Tools" and "tools.numlm.com" as the first thing a reader sees.
The right og:image: 1200×630, and why the middle matters
1200×630 pixels, a 1.91:1 ratio, under 1MB, PNG or JPEG. That single line covers Facebook, LinkedIn, X, Slack and Discord. Below 600×315 the image is upscaled and looks soft; below 200×200 Facebook refuses it entirely and falls back to a text card. Files above 8MB are refused by Facebook and Discord, and above 5MB by LinkedIn.
Different clients crop differently around the same 1.91:1 frame, and KakaoTalk prefers a 2:1 image (800×400 or larger). The practical defence is a safe area: keep the logo and any text inside the middle 1080×600 of a 1200×630 canvas. Everything outside that band should be background you can afford to lose.
Text in a share image should be large. The card is rendered at roughly 500 CSS pixels wide in a feed, so 1200px of image becomes 500px on screen — a 24px label in your design file is about 10px to the reader. Two to six words at a very large size beat a sentence.
- SVG does not work as a share image on most platforms. Export a PNG.
- Use an absolute https URL. A relative path like /og.png is the single most common reason a preview is blank, because the scraper resolves it against its own host, not yours.
X (Twitter) cards: summary vs summary_large_image
twitter:card takes one of two useful values. summary shows a small square thumbnail on the left with the title and description on the right, and needs an image of at least 144×144. summary_large_image shows a wide 1.91:1 image with the title over it, and needs at least 300×157 — up to 4096×4096 and 5MB. An animated GIF is shown as its first frame.
X reads og:title, og:description and og:image when the twitter:* equivalents are missing, so duplicating all of them is unnecessary. Add twitter:card, and twitter:site or twitter:creator when you want the account attribution; leave the rest to Open Graph. This tool omits duplicate twitter:* tags by default for that reason, with a toggle if you prefer them explicit.
The X card layout has changed more than once since 2023 — headlines were removed from link previews and later restored as a strip over the image. Treat the X preview here as an approximation of the current wide card, and remember that the destination URL and the image are the parts that have stayed constant.
How Discord and Slack build a preview
Both read Open Graph first and fall back to twitter:* tags, so a page with good OG tags already previews well in both. The differences are in the details, and both are absent from every competing generator.
Discord draws a coloured bar down the left edge of the embed and takes that colour from your theme-color meta tag; without it the bar is grey. It shows a wide image when twitter:card is summary_large_image (or when the image is clearly landscape), and an 80×80 thumbnail on the right otherwise. Discord also renders the description at full length — up to roughly six lines — so it is the platform where a longer og:description actually pays off.
Slack prints the site name with your favicon as a header line above the title, then the description at around three lines. Slack is also the only mainstream client that renders twitter:label1 / twitter:data1 (and label2 / data2) as key-value fields under the description — a natural place for "Reading time · 6 min" or "Price · $19".
KakaoTalk, LinkedIn and other regional previews
KakaoTalk reads Open Graph and is the dominant sharing surface in Korea, so a Korean page with no og:image loses its preview where it matters most. Kakao recommends a 2:1 image of 800×400 or larger; an image close to square drops the card to a small thumbnail layout. Kakao caches aggressively, and the cache is cleared from the Kakao Developers tools (a login is required).
LinkedIn recommends 1200×627 and caches a scraped preview for about seven days. Editing your tags does not refresh the card by itself — run the URL through LinkedIn Post Inspector, which re-scrapes on demand.
Naver’s in-app browser and KakaoStory follow the same Open Graph tags, and messaging apps like WhatsApp and Telegram read og:title, og:description and og:image with their own size preferences. There is no per-platform tag to add: one good Open Graph set plus twitter:card covers all of them, which is why this tool generates one set and previews it in several shapes rather than generating several sets.
Why the preview still shows the old image
Every platform caches what it scraped. You changed og:image an hour ago, the card still shows last month’s picture, and nothing you do on your own site will change that until the platform re-scrapes. Each one has a tool for forcing it: Facebook Sharing Debugger, LinkedIn Post Inspector, and the Kakao Developers cache reset. X no longer offers a public card validator; posting the link in a draft or from a test account is the practical check.
Two things make a stale cache much more likely. The first is reusing the same image URL for new artwork — the scraper sees a URL it already knows and does not fetch it again. Ship a new filename, or add a version query such as og.png?v=3. The second is a URL that redirects: many scrapers follow only one hop, and a card that works in a browser can still fail for the bot.
- If a card renders in one app and not another, the difference is almost always image size or file size, not the tags.
- If nothing renders anywhere, check that the page is reachable without a login and that robots.txt does not block the scraper user agents (facebookexternalhit, Twitterbot, LinkedInBot, Slackbot-LinkExpanding, Discordbot).
Adding the tags in SvelteKit, Next.js, Nuxt and plain HTML
In plain HTML the tags go inside <head>, in any order, after charset and viewport. Order has no meaning to parsers; the order this tool uses simply groups related tags so a human can read them.
In SvelteKit put them in <svelte:head> inside the page component (or the layout for site-wide defaults). Values interpolate normally, and a page-level tag overrides a layout-level one only if you conditionally render it — SvelteKit does not deduplicate meta tags for you, so avoid declaring the same og:title in both places.
In Next.js App Router, export a metadata object (or generateMetadata for dynamic values) with openGraph and twitter sections; Next writes the tags and handles escaping. metadataBase is what turns a relative image path into the absolute URL scrapers need. In Nuxt, useSeoMeta({ title, ogTitle, ogImage, twitterCard, … }) does the same job with flat camelCase keys.
- Whatever the framework, verify the rendered output, not the source: open view-source on the deployed page and confirm the tags are in the served HTML. Tags injected by client-side JavaScript after load are invisible to every social scraper.