Google's Rich Results Test says one of our game pages has four valid structured-data items. We wrote one of them.
The other three — an Organisation, a Review snippet and a Software App — are published by a document we do not control, do not host, and cannot read from our own page. It arrives in an <iframe>. It brings a star rating with it, and Google's own tool reports that rating as ours.
Nobody did anything wrong to make this happen. Our markup is clean and always has been. The partner's markup is exemplary — genuinely one of the better structured-data implementations you will read. Put the two together with a normal load-time iframe and you get a third thing that neither party wrote.
If you embed anything on your site — a game, a video, a map, a booking widget, a review carousel — this is a five-minute check you have probably never run.
The short version
- Two pages, same template, same day, one difference. The page whose iframe points at a document with a JSON-LD graph: 4 valid items. The page whose iframe points at a document with none: 1 valid item. Same tool, five minutes apart.
- The extra three item types are Organisation, Review snippets and Software apps. The detected Review snippet carries an
@idon the provider's domain, not ours. - 0 of 200 of our live game pages carry a rating in their own markup. 190 of 200 of the embed documents they load do.
- The Software App item detected on our page is named after the platform, not the game — it is the provider's Android app listing.
- It is not a games-industry quirk, and it is not universal either: of 11 public embed endpoints we could read, 4 serve parseable JSON-LD and 1 serves a rating.
- A text search for the property name is not a test. On 4 of those embed documents, searching the HTML for
aggregateRatingreturned true while the parsed structured data contained no such property.
What I measured, and what I am not claiming
Everything below is a count of published metadata and tool output, taken on 8 August 2026. Three honest limits, stated before the numbers rather than after them.
I am not claiming Google will show a star rating for our site. The Rich Results Test reports eligibility, and Google states plainly that it does not guarantee rich results even with correct markup. What the tool reports is that the item exists, is valid, and is attributed to our URL. Whether it ever reaches a search result is a different question I did not measure.
I am not claiming Google documents this behaviour as a rule. I looked. Google's structured-data documentation does not contain a statement of the form "markup inside an iframe is attributed to the parent". What it contains is an acknowledgement that the situation arises, which I quote further down. Treat the mechanism as measured on one date, on two URLs, with a control — not as a documented guarantee.
I could not check whether the rating is visible to a human inside the player. That frame is cross-origin, so the host document cannot read into it, and a screen capture of a cross-origin game canvas is not evidence of anything — it comes back solid black even while the game runs perfectly. So the honest statement is narrower than the tempting one: our page's own text shows no rating, and I verified that directly. What the player renders inside its own frame is unmeasured.
One method rule that changed a number in this article. Do not search the HTML for a property name; parse the JSON-LD and look for the property as a real key on a real node. Four of the embed documents I probed contain the string aggregateRating somewhere in their markup or scripts while publishing no such property. A substring test would have reported four ratings that do not exist. My harness was validated against a document that definitely has a parsed rating (detected) and one where the string appears only in an HTML comment and in body text (not detected, while the substring test said yes).
The controlled pair
This is the whole finding in one table. Both URLs are generated by the same script, from the same template, and their own JSON-LD is identical in shape: one block containing a BreadcrumbList and a VideoGame, with no rating and no review anywhere in it. I verified that by parsing both pages, not by reading them.
The only relevant difference between them is which document the static <iframe> loads. One loads a partner page that publishes a JSON-LD graph. The other loads a partner page that publishes none.
| Google Rich Results Test, 8 Aug 2026 | Page A — embed has a JSON-LD graph | Page B — embed has no JSON-LD (control) |
|---|---|---|
| Crawled at | 21:40:29 | 21:45:13 |
| Valid items detected | 4 | 1 |
| Breadcrumbs | 1 valid item | 1 valid item |
| Organisation | 1 valid item | — |
| Review snippets | 1 valid item | — |
| Software apps | 1 valid item (1 non-critical issue) | — |
| Rating in the page's own JSON-LD | none | none |
| Rating in the embed document |
ratingValue 4.6, ratingCount 205
|
none — 0 JSON-LD blocks |
Page A is Mystery Squishy Dumpling Blind Box, a partner game credited on the provider's own page to Universe 25. Page B is Deadly Descent. Both are third-party games playable on SlowDen; neither is a SlowDen Original, and this article makes no claim about either game's quality.
Three of the four rich-result item types vanish when the embed changes. That is what a control is for: it rules out the explanation that our own template quietly grew a rating, and it rules out the tool inventing items.
The detail that settles provenance is inside the Review snippet item. Its @id is https://playgama.com/game/mystery-squishy-dumpling-blind-box#Game — a URL on the provider's domain, reported by Google as a valid item on a slowden.com URL.
What is actually inside the embed
I expected a rating. What the embed document publishes is an entire identity graph.
Parsed from the frame's own URL, its single JSON-LD block contains an Organization, a WebSite and an ItemPage, and nested inside the ItemPage is the game itself. The game node is co-typed:
"@type": ["VideoGame", "WebApplication"],
"name": "Mystery Squishy Dumpling Blind Box",
"@id": "https://playgama.com/game/mystery-squishy-dumpling-blind-box#Game",
"author": { "@type": "Person", "name": "Universe 25" },
"offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" },
"aggregateRating": { "@type": "AggregateRating",
"ratingValue": 4.6, "ratingCount": 205,
"bestRating": 5, "worstRating": 1 }
Look at those three properties together, because that combination is not decorative. Google's Software App rich result is valid on SoftwareApplication and its subtypes including WebApplication, and its required properties are name, offers.price, and aggregateRating or review. The embed document carries all three. It is a complete, qualifying rich-result item.
Which produces a result worth sitting with. There is no Google rich result for a game — neither VideoGame nor Game appears in Google's list of supported features. The only one a game page can earn is Software App, and it requires a rating. A site with no rating system of its own is therefore locked out of it by construction. Our pages are locked out of it — and Google's own tool says one of them qualifies anyway, on numbers we did not collect.
The enclosing graph goes further than the game. Alongside it the embed publishes the platform's own WebSite node, a MobileApplication node for the platform's Android app, and a publisher Organization carrying the company's legal name, its VAT and DUNS identifiers, a registered postal address, a support email, a named founder with job title, eight sameAs social profiles and a platform marketing description. I am describing the field types rather than reprinting the values, because none of it is mine to republish — but all of it is what Google reads on our URL.
That also explains the oddest line in the test result. The Software App item detected on our game page is not named after the game. It is named after the platform: it is the provider's Android app listing, surfacing as a Software App rich-result item on a page about a browser game.
One more thing worth noticing, and it closes a loop from last week's article about the game-metadata field nobody fills in. This graph is close to a model implementation — genre, device list, operating system, author, offer, publish date, platform list, a PlayAction. It contains zero schema.org accessibility properties. Not one. The field that tells a player whether their phone is enough is absent even here, in markup this careful. Google pays for the rating field. It pays nothing for the accessibility field. The incentive is visible in a single document.
How much of a catalogue this touches
Two pages prove a mechanism. The next question is scale, so I measured every page and every embed we ship. All figures are live, fetched from the public site and the public embed URLs on 8 August 2026, and both sides came back complete — 200 of 200, zero fetch errors.
| Measured live, 8 Aug 2026 | Result |
|---|---|
| Game pages returning HTTP 200 | 200 of 200 |
| Game pages carrying a rating in their own parsed JSON-LD | 0 |
| Game pages shipping the partner iframe in static HTML | 200 |
| Embed documents returning HTTP 200 | 200 of 200 |
Embed documents serving a parsed aggregateRating
|
190 |
| Embed documents serving none | 10 |
The split between 190 and 10 is not random, and the reason is useful if you are auditing your own site. All 190 rated embeds are served from the platform's own domain. All 10 unrated ones are served from standalone game domains the platform routes to instead — a different, much smaller document, roughly 32 KB against 99 KB, with zero JSON-LD blocks in every single case. The same provider, two delivery paths, and only one of them hands you a graph.
So "my provider publishes structured data" is not a per-provider fact. It is a per-URL fact.
One number I am deliberately not publishing. I have the rating values for all 190 and it would be easy to average them. I am not going to, because an average would read as a quality claim about a catalogue whose ratings we did not collect and cannot stand behind. What is fair to report is the shape, because the shape is the point: the values run from 3.9 to 4.8, exactly one of the 190 sits below 4.0, and none sits below 3.5. An inherited rating is not a neutral signal. A page that inherits one inherits a flattering one.
For clarity about what is what: all 200 games in that catalogue are third-party partner games, credited to their studios. SlowDen's own game sits outside that registry. Nothing in this article is a claim about who made any of them.
Is this a game-portal thing?
That was my first assumption and it is wrong in both directions. I probed 14 public embed endpoints across six categories, parsing the JSON-LD of each. Eleven returned a document I could read.
| Embed endpoint | Kind | Parsed JSON-LD | Rating? |
|---|---|---|---|
| Game portal (partner player) | game |
Organization, WebSite, ItemPage → VideoGame+WebApplication
|
yes |
| Video player A | video | VideoObject |
no |
| Live-video player | video | Organization |
no |
| Archive player | video |
BreadcrumbList, ListItem
|
no |
| Video player B | video | none | no |
| Music player A | audio | none | no |
| Music player B | audio | none | no |
| Map embed | map | none | no |
| Social post embed | social | none | no |
| Game widget (indie marketplace) | game | none | no |
| Game embed (HTML5 supplier), 2 games | game | none | no |
| Code sandbox embed | code | not measured — 403 to an automated request | unknown |
| Game portal (major) | game | not measured — 401, no public embed endpoint | unknown |
| Game embed (second HTML5 supplier) | game | not measured — no public endpoint found | unknown |
Two things follow. Most embeds ship no structured data at all, so this is not a general emergency — and it is also not predictable from the category. Two video players in the same category differ from each other. Two game embeds in the same category differ from each other. The only way to know is to look at your own embed URL.
A note on the three unmeasured rows, because getting this wrong is how false findings get published: a 401 or a 403 is not a zero. One endpoint requires authentication and one blocks automated requests. Both may well serve structured data to a browser. They are recorded as unknown, not absent.
And the four grep false positives all came from this group: a substring search for aggregateRating returns true on two video players, a music player and one other — none of which publishes the property. If you audit with grep you will find ratings that are not there.
Nobody did anything wrong, and it still crosses a guideline
This is the part I want to be careful about, because the easy version of this story is an accusation and the true version is not one.
The provider wrote correct, thorough markup on its own page and made that page embeddable, which is the entire point of an embed. We embedded it the ordinary way. Neither of us wrote a rating onto a SlowDen URL. And yet, read against Google's published guidance, the resulting page sits on the wrong side of two lines.
From Google's general structured data guidelines:
"Don't mark up content that is not visible to readers of the page."
"Your structured data must be a true representation of the page content."
Our page's own text contains no rating: I checked, and there are zero occurrences of the rating value, the rating count, the words "rating", "rated" or "review", and zero star glyphs anywhere in the rendered text we serve.
From Google's review snippet guidelines:
"Don't aggregate reviews or ratings from other websites."
Which is precisely what a load-time embed does on your behalf, silently, at whatever scale you embed at.
And here is the closest thing to an acknowledgement in Google's own text that widget-delivered markup counts as being on the host page. It appears in the specific rule about businesses reviewing themselves, describing how such a review can arrive:
"…either directly in their structured data or through an embedded third-party widget…"
Read that precisely. The ineligibility rule it belongs to is about a local business or organisation hosting reviews of itself, which is not our situation and probably not yours. I am not claiming that rule applies here. What the sentence establishes is narrower and more useful: Google treats structured data arriving via an embedded third-party widget as structured data on the host page. That is the assumption my measurement rests on, and Google's documentation states it in passing rather than leaving it to inference.
Set the search engine aside for a moment, though, because the trust problem does not depend on it. If a visitor ever sees stars next to your domain in a result, they will read those stars as yours. Ours are not. We collect no ratings, we have never published one, and we are not in a position to defend a number a partner computed on a different site from a different audience. That is a reason to care about this even if Google never renders it.
Why we have not applied the obvious fix
There is a one-line fix and we are not using it, and saying why is more useful than pretending the problem is hard.
Our generator already has a flag that creates the game frame on click instead of at page load. Flip it and the frame does not exist when a crawler renders the page, which would very likely end the attribution.
It stays off for a reason that outranks a flattering rating: nobody has verified what the provider counts when the frame is created on click rather than at load. Every embed URL carries a partner parameter that credits the play, and that parameter is how the arrangement works at all. Reasoning about our own markup cannot answer a question about someone else's counting. A rating we did not ask for is a smaller harm than a play that does not register, so the flag stays where it is until the counting question is answered by the provider rather than by us guessing.
There was also a second, plainer reason it was turned off in the first place: a click-to-start poster in front of a player that already has its own start screen made it three clicks to reach a game.
If you are in the same position, the honest options are the same three. Ask the provider whether their markup is meant to travel with the embed — many providers would rather it did not. Create the frame after a click, once you know what that does to whatever the provider measures. Or accept it deliberately and write down the reason, which is what we have done, in a comment next to the iframe so the next person does not silently "fix" it.
Five minutes on your own site
This costs almost nothing and I would be surprised if most sites with embeds have run it.
- Write down what you think your page publishes. Open your own template and list the structured-data types you wrote. Ours is two: a breadcrumb and a game.
- Run the page through Google's Rich Results Test. Compare its list of detected items to your list. Anything extra did not come from you.
-
Expand each unexpected item and read its
@idandurl. A property pointing at a domain that is not yours tells you exactly where it came from. - Fetch your embed's URL on its own and parse its JSON-LD. Parse it — do not search the text for property names, or you will find four ratings that do not exist.
- Test a page with a different embed as a control. This is the step that turns a suspicion into a finding. If you have only one embed provider, compare against any page on your site that has no embed at all.
If you ship an embeddable widget rather than host one, the same measurement points the other way and is worth ten minutes of your time: whatever your frame document publishes, your customers publish too. A rating, an offer, a company identity, a founder's name. Structured data on an embeddable page is not the same object as structured data on a normal page, and most embeddable pages appear to have been built by copying the normal one.
What we changed, and what we did not
Nothing about the site changed today as a result of this. That is deliberate, and it is the honest end of the story rather than a tidy one.
What did change is that the decision is now written down where it cannot be lost: our build refuses, as a fatal error, to emit any rating property in any structured-data block, tested by deliberately poisoning a scratch copy of the generator to confirm the guard actually fires. That protects against the version of this problem we can control — someone adding a rating because a rich result requires one. It does nothing about markup arriving in a frame, and pretending otherwise would be worse than the gap.
The gap that remains, stated plainly: 190 of our game pages are eligible, in Google's own tool, for rich results built from a rating we did not collect. One of them has already been recorded as a valid review-snippet item by Search Console. We know why, we know the one lever that would change it, and we are not pulling that lever on an unverified assumption about someone else's counting.
Questions
Can structured data inside an iframe really be attributed to the host page?
We measured a case where it was. Two pages from the same generator, built from the same template on the same day, differ only in which document their static iframe points at. Google's Rich Results Test reported 4 valid items on the page whose embed carries a JSON-LD graph and 1 valid item on the page whose embed carries none, and the detected review-snippet item carried an @id on the provider's domain. Google does not publish a rule stating that this happens, so treat it as a measured behaviour on one date rather than a documented guarantee.
How do I check what my own embeds publish on my behalf?
Run your page through Google's Rich Results Test and compare the detected items against the structured data you actually wrote. Anything extra came from somewhere else. Then fetch your embed's URL directly and parse its JSON-LD. Do not use a text search for the property name: on four of the embed documents we probed, searching the HTML for aggregateRating returned true while the parsed structured data contained no such property.
Is this a real problem or a curiosity?
Google's general structured data guidelines say not to mark up content that is not visible to readers of the page, and its review snippet guidelines say not to aggregate reviews or ratings from other websites. A host page can end up in both positions without writing a line of markup. Separately, and independently of any search engine, a rating a visitor reads as yours that you never collected is a trust problem you cannot defend.
Which kinds of embed carry structured data inside them?
Fewer than you would guess, and it is not predictable by category. Of 11 public embed endpoints we could read, 4 served parseable JSON-LD and only 1 served a rating. Two video players in the same category behaved differently from each other, and so did two game embeds. Two further endpoints refused an automated request, which is not the same as serving nothing, and are recorded as unknown.
Should I stop embedding third-party content?
No. The embed is usually the product. The point is to know what it publishes in your name and to check rather than assume. If your provider ships structured data you cannot stand behind, the options are to raise it with them, to create the frame after a click, or to accept it deliberately with the reason recorded. Creating the frame on click can affect whatever the provider counts, so verify that before changing it.
Does the embed's canonical tag affect the host page too?
We did not measure that and are not claiming it. The embed document does declare its own canonical, og:url and og:title pointing at the provider's domain, and anything fetching the frame's URL can see them. What we measured is structured-data attribution, not canonicalisation. The rest is unverified.
Why does a page with no rating system care about rich results at all?
Because the only Google rich result a game page can earn is Software App, and it requires an aggregateRating or a review. There is no rich result for a game as such. A site that collects no ratings is locked out by construction, and the only honest route in is to build a real rating system of its own. Copying a partner's number is not a shortcut, it is a false claim.
Written on SlowDen, a place to put a browser game where people can find it and play it — no download for the player, no store page for the developer. Games there come from creators, partners and third-party sources, each credited to whoever made it. Our creative challenge round, Slow Cook, closes on 31 August 2026: you get a prompt, you build something around it, you submit it for consideration. Selected entries have a chance to be featured and selected winners may receive a shoutout on SlowDen's social accounts — that is the honest list, and there is nothing guaranteed beyond it. Submit a browser game · See the Slow Cook challenges · More articles
Top comments (0)