DEV Community

OnePassApps
OnePassApps

Posted on

One Image for Every OnePassApps Link: What the Open Graph and Twitter Card Tags Say

I work on OnePassApps, so this is our own site, and everything below is a measurement of our own public pages - fetched and decoded, not a guess.

When you paste a link to app.onepassapps.com into a chat app, a document, or a social post, what a reader sees before they click is not the page. It is a preview: a title, a line of description, and one image. That preview is built from tags in the page's <head>, and it is a layer of the site that almost nobody looks at.

So I looked at it. Sixteen public URLs, fetched one by one, and the preview image itself decoded pixel by pixel.

How this was measured: plain HTTPS GETs with a browser User-Agent - no JavaScript, no browser tab, no sign-in - one request per URL in the sitemap. For each page I read the Open Graph and Twitter card tags out of the <head>. The preview image was then downloaded and its PNG chunks decoded locally (IHDR for the header, then zlib-inflate and un-filter the scanlines), so the colours below are the file's own bytes rather than a browser's rendering of it.

One image for every link on the site

All sixteen pages point at the same preview file:

https://app.onepassapps.com/og-image.png
Enter fullscreen mode Exit fullscreen mode

It answers 200 with image/png, 42,818 bytes, 1200 by 630 pixels, 8-bit truecolour with no alpha channel, not interlaced.

Decode it and it is a single composition: a near-black background at #0B0D0F, a teal circle at #00E5D0 holding the robot mark, the wordmark "OnePassApps" in off-white #F8F5EF, and the line "Useful apps, one membership" underneath in grey #A3A3A3.

The same file backs every one of the sixteen URLs. The title and the description change from page to page; the picture never does. So a reader scrolling a chat thread sees the OnePassApps card over and over, and the only thing that tells two links apart is the line of text under it.

The tags are consistent, in a way that is easy to miss

Per page, on all sixteen:

  • og:title matches the page's <title>, and twitter:title matches it too.
  • og:description and twitter:description are both the page's meta description, word for word.
  • og:url is the page's own URL, matching its canonical exactly.
  • og:type is website, og:locale is en_GB, og:site_name is OnePassApps.
  • og:image and og:image:secure_url are the same absolute URL, og:image:type is image/png, og:image:width is 1200, og:image:height is 630.
  • twitter:card is summary_large_image, twitter:url is the page's own URL, twitter:image is the same PNG.

Two things in that list are worth pulling out.

The alt text is the same on every page. og:image:alt reads "OnePassApps — Useful apps, one membership" on all sixteen pages, and twitter:image:alt repeats it. The alt describes the card, not the page it stands in for. That is a deliberate-looking choice - the card is the brand, so the brand's name and line is the honest description - but it does mean a screen reader hears the same sentence whatever it is announcing.

No account is attached to the card. There is no twitter:site and no twitter:creator on any of the sixteen pages. The card renders and it is unattributed: no handle, no account name, nothing for a reader to follow back to. If you are building a preview and want the card to name the account, that tag is where it goes.

One type that does not match the page

og:type is website on all sixteen pages - including the seven studios and the two hosted apps. The structured data on those same pages calls them WebApplication nodes, with applicationCategory values of UtilitiesApplication, ReferenceApplication and EntertainmentApplication, and a featureList naming each studio's tools.

So the JSON-LD says "this is an app" and the Open Graph says "this is a website", on the same URL, on the same request. Both are defensible in their own vocabulary, but if you are deciding how to render a preview, the JSON-LD is the richer description.

Two routes that behave differently

  • /privacy is a 301 whose Location header is /terms#privacy. The privacy notice is a section of the terms document, not a page of its own, and a fragment is never sent to the server - so /terms is served identically either way.
  • /support answers 200 and is linked from the home page, and it is the one page on the site that asks crawlers to stay away: its robots tag reads noindex, nofollow. It carries no canonical tag and no structured data block at all. A reader who clicks it gets a support and feedback page - "Create and follow support requests and product feedback for OnePassApps." - while a crawler is told there is nothing here to index.

The questions on the guides are not marked up as questions

Both guide pages end with a "Common questions" section - the NewsFlow guide asks three of them, about listening without an account, about whether every story from a source is included, and about what it costs.

None of that is marked up as structured data. The JSON-LD on both guide pages is the same four nodes - Organization, WebSite, WebPage, BreadcrumbList - with no FAQPage and no QAPage anywhere in the document. The questions are in the page as headings and paragraphs; they are not in the page as questions and answers a search engine can quote.

Check it yourself

curl -s https://app.onepassapps.com/studios/image | grep -o '<meta property="og:[^>]*>'
curl -s https://app.onepassapps.com/studios/image | grep -o '<meta name="twitter:[^>]*>'
curl -s https://app.onepassapps.com/og-image.png -o card.png && file card.png
Enter fullscreen mode Exit fullscreen mode

No login, no uploads, nothing to install - the same browser tools the guides walk through, described in one page each. Start with the Image Studio, or browse the app guides.

Disclosure again: I work on OnePassApps, the team behind app.onepassapps.com.

Top comments (0)