BlogFindings
Fourteen noscript elements on five pages, and not one held text
Counted with an HTML parser on 25 August 2026 over five real pages this scanner captured and stored on 15 July 2026, the initial HTTP responses hold 14 noscript elements. Between them they carry 11 img tags, one tag manager iframe, one CSS rule of 57 characters and zero characters of text. The one element HTML defines for a reader that does not run scripts is the one place on these pages where nobody wrote a sentence.
This post counts that on the only pages this site is entitled to count: the five real captures already frozen in its own fixtures, fetched on 15 July 2026 and parsed again on 25 August 2026. The answer is short enough to give away. Fourteen noscript elements, 13 child elements, and no text. The same five files produced our earlier counts of alt text on 466 images and of 85 meta elements in five heads; this is the same exercise pointed at the one element that was supposed to be the fallback.
In short
- Counted with an HTML parser on 25 August 2026 over five real pages this scanner captured and stored on 15 July 2026, the raw HTTP responses hold 14 noscript elements: 11 on gymshark.com, 2 on webflow.com, 1 on the Wikipedia article, and none on the MDN or astro.build pages.
- Those 14 elements contain 13 child elements between them and zero characters of text. The children are 11 img tags, one Google Tag Manager iframe and one style element holding a single CSS rule of 57 characters. One noscript element is empty.
- Ten of the 11 images carry alt text, 105 characters and 19 words in total, and every word of it is a navigation label or a payment brand name. The eleventh is a 1 by 1 pixel with an empty alt on the Wikipedia page.
- Running the pages' own JavaScript cut the child elements inside noscript from 13 to 7. On gymshark.com seven of ten fallback images were removed by the page's own code, taking the strings Visa, Mastercard, Paypal, Apple Pay, Klarna, American Express and Afterpay with them.
- The WHATWG HTML Standard, section 4.12.2, calls noscript a blunt instrument and advises authors to avoid it, and Google's JavaScript SEO documentation, Last updated 2026-03-04 UTC, does not contain the string noscript at all.
| Page | noscript | Child elements | Text characters | What is inside | Stored parity |
|---|---|---|---|---|---|
| gymshark.com | 11 | 10 | 0 | 10 img, 1 empty element | 0.958 |
| webflow.com | 2 | 2 | 0 | 1 iframe, 1 style rule | 0.980 |
| en.wikipedia.org | 1 | 1 | 0 | 1 tracking pixel | 0.994 |
| developer.mozilla.org | 0 | 0 | 0 | No noscript element | 0.988 |
| astro.build | 0 | 0 | 0 | No noscript element | 1.000 |
| All five | 14 | 13 | 0 | 11 img, 1 iframe, 1 style | n/a |
What noscript is for, and which reader it was written for
The WHATWG HTML Standard defines the element in section 4.12.2, read at https://html.spec.whatwg.org/multipage/scripting.html on 25 August 2026, and the definition is one sentence: the noscript element represents nothing if scripting is enabled, and represents its children if scripting is disabled. The specification then says what it is for, which is more interesting than what it is. It is used, in the standard's words, to present different markup to user agents that support scripting and those that do not support scripting, by affecting how the document is parsed.
That last clause is the mechanism and it is the part that decides what a crawler gets. The same specification notes that the noscript element is handled differently by the HTML parser based on whether scripting mode was Disabled when the parser was invoked. With scripting disabled, the contents are parsed as ordinary markup and the children exist as elements. With scripting enabled, the contents are parsed as raw text and a browser then discards them. So a program that parses HTML without an engine, which is what our raw capture models and what any fetch-only client is, sees the children as real nodes. It does not have to opt in. They are simply there.
The MDN reference for the element, last modified 24 April 2026, states the same thing in author-facing language: noscript defines a section of HTML to be inserted if a script type on the page is unsupported or if scripting is currently turned off in the browser. MDN also records the content model, which matters for two of the elements counted below. Inside a head element with scripting disabled, a noscript element must contain only link, style and meta elements. Outside the head there is no such restriction and it may hold ordinary flow content, which is to say paragraphs, headings and lists.
This post does not establish which crawlers run scripts and which do not, and no count of stored files could. What it establishes is narrower and still worth having: for any client that parses without executing, the contents of a noscript element are readable text and markup, and on these five pages that content amounts to nothing. We have published adjacent evidence before, including the observation that the Common Crawl archive is built without JavaScript, but the general question of who renders is not settled here.
Flow: HTML response with noscript to Parser scripting mode; Parser scripting mode (no engine) to Disabled: children parsed as markup; Parser scripting mode (engine present) to Enabled: contents parsed as raw text; Disabled: children parsed as markup to Fetch only client reads the children; Enabled: contents parsed as raw text to Browser represents nothing.
Fourteen noscript elements, and zero characters of text
Parsing the five stored raw responses with htmlparser2 on 25 August 2026 finds 14 noscript elements. They are not evenly spread. The gymshark.com homepage carries 11, webflow.com carries 2, the Wikipedia article on web crawlers carries 1, and the MDN HTML reference and astro.build carry none at all. Two of the five pages in this set have never used the element.
Between those 14 elements there are 13 child elements and, once whitespace is discounted, zero characters of text. Not a short sentence, not a link, not a heading. The full inventory of what a fetch-only reader would find inside every noscript element on all five pages is 11 img tags, one iframe, and one style element holding a single CSS rule 57 characters long. One noscript element, in the head of gymshark.com, contains nothing whatsoever.
It is worth being clear about what that does and does not mean, because the obvious reading is the wrong one. This is not evidence that anyone neglected the element. The stored parity figures for these five pages run from 0.958 to 1.000, which is to say that all five already ship their prose in the initial HTTP response and none of them has any prose that needs rescuing. On a page whose text is present without JavaScript, a fallback with words in it would be a duplicate. The finding is not that these sites failed a test. It is that the element widely recommended as the way to serve a non-scripting reader is, on real pages, not carrying words, and any advice that treats it as a place to put content is describing a practice these five pages do not follow.
The comparison worth drawing is with the page in this set that would have benefited most. gymshark.com is the lowest-parity capture and the one whose initial response leans hardest on client-side code, which is the case discussed at length in our note on what a crawler meets on a real storefront. It is also the page carrying 11 of the 14 noscript elements, and every one of them holds an image or nothing. Five pages cannot support a claim about a relationship between parity and noscript use, and none is being made. What can be said is that on the one page here with the most to gain, the element was used for pictures.
Eleven images, 19 words of alt text, and one tracking pixel
The 11 img elements are the only thing in this set that carries readable strings at all, and they carry them in an attribute rather than as text. Ten of the 11 have a non-empty alt, totalling 105 characters and 19 words across all five pages. Those words, in full, are Blog, Students get an extra 12% off, Email Sign Up, Visa, Mastercard, Paypal, Apple Pay, Klarna, American Express and Afterpay. Seven of the ten are payment brand names in a footer badge strip, two label a link and a button in the page body, and one is a promotion.
The eleventh image is the interesting one. On the Wikipedia article, a single noscript element sits inside the main element and holds an img of width 1 and height 1 with an empty alt, pointing at Special:CentralAutoLogin. It is a login tracking pixel. On the one page in this set where a noscript element sits in the main content region rather than in chrome, the thing being served to a non-scripting reader is a beacon.
The two remaining children are worth naming precisely because neither is content either. webflow.com has a noscript element directly inside body holding an iframe pointing at googletagmanager.com, which is the standard tag manager fallback, and a second one in the head holding a style element with one rule: an attribute selector setting visibility to visible with an important flag, for elements that would otherwise be hidden until an animation library initialised them. That rule is the closest thing in this whole set to the element doing its designed job. It repairs a page that would otherwise be blank in places without JavaScript, and it does so in 57 characters of CSS, which is a legitimate and rather elegant use.
None of these 13 things is text a machine could quote. That distinction is the one that matters for generative engine optimisation, because an answer engine cites passages rather than assets, and it is the same distinction we drew when counting 85 links that carried no anchor text on these same captures. An alt attribute is real accessible content and it is not nothing. Nineteen words of it, nine of which are the names of card schemes, is not a fallback version of a homepage.
| Child element | Count | Page | What it carries |
|---|---|---|---|
| img | 10 | gymshark.com | Non-empty alt, 105 characters and 19 words in total |
| img | 1 | en.wikipedia.org | 1 by 1 pixel, empty alt |
| iframe | 1 | webflow.com | Google Tag Manager container, no text |
| style | 1 | webflow.com | One CSS rule, 57 characters |
| (empty) | 1 | gymshark.com | A noscript element in head with no children |
| Any text node | 0 | All five | Zero characters across the whole set |
Running the JavaScript emptied eight of the 15 fallbacks
Every capture in these fixtures is stored twice, as the raw HTTP response and as the rendered DOM after a real browser has run the page. Comparing the two here produces the result that is hardest to guess in advance: the pages dismantle their own fallbacks.
In the raw responses, 14 noscript elements hold 13 child elements. In the rendered DOM there are 15 noscript elements, gymshark.com having gained one that holds a tag manager container iframe and is not present in the raw response, and they hold 7 child elements between them. Eight of the 15 are completely empty after rendering, against one of 14 before. Six of the 13 things that a fetch-only reader would have found are simply not in the rendered document.
The whole of that difference is on one page. gymshark.com goes from 11 noscript elements holding 10 images to 12 holding 3 images and one iframe, with 8 empty. The three that survive are the ones whose src points at the site's own image endpoint; the seven that do not are the footer payment badges loaded from an external asset host. Their alt strings, Visa, Mastercard, Paypal, Apple Pay, Klarna, American Express and Afterpay, are 59 of the 105 characters of alt text the raw response carried, and after the page's own JavaScript has run they are gone from the noscript blocks. webflow.com and Wikipedia are unchanged between raw and rendered.
The mechanism is not mysterious and it is not a bug. A component framework that re-renders a subtree writes new children into it, and children that only existed to cover for the framework not running are exactly what it drops. It is worth stating plainly all the same, because it inverts the usual advice about checking a page twice. On these captures, rendering added link targets nowhere, as we found when JavaScript added no new crawl paths, and here rendering actively removed content that the initial response contained. A reader that runs scripts and a reader that does not are not getting more and less of the same document. They are getting different documents, which is the point our note on two layers deciding whether AI can read your site has been making from the other direction.
Raw HTTP response
- 14 noscript elements
- 13 child elements: 11 img, 1 iframe, 1 style
- 1 element empty
- 105 characters of alt text inside noscript
Rendered DOM
- 15 noscript elements, one injected by a tag manager
- 7 child elements: 4 img, 2 iframe, 1 style
- 8 elements empty
- 46 characters of alt text inside noscript
Two in the head, twelve in the body, and seven inside a footer
Where a noscript element sits decides what it is allowed to contain and, for a scanner, which part of the page it counts as. Of the 14 in the raw responses, 2 are in the head and 12 are in the body. Both head cases conform to the specification's stricter content model for that position: gymshark.com has an empty one, and webflow.com has one holding a style element, which is one of the three permitted children along with link and meta.
The 12 in the body split by region, and the split is the useful part. Seven of gymshark.com's ten body-level noscript elements sit inside a footer element. Three more sit inside an anchor or a button within a figure. webflow.com's remaining one sits directly under body, and the Wikipedia one sits inside main.
That footer number matters because of a rule in our own extractor that has nothing to do with noscript. Anything inside nav, header, footer or aside is classified as boilerplate, and boilerplate wins over every other classification, which is the rule that produced the outcome where an h1 inside a header element counted as no h1 at all. So even in a hypothetical version of the scanner that read noscript subtrees, seven of the 11 images would land in boilerplate rather than in main content. The one that would land in main content is the Wikipedia login pixel.
There is a second reason the placement counts are a floor rather than a total, and it belongs here rather than buried in the limits. The gymshark.com raw capture is exactly 3,145,728 bytes, which is the maxHtmlBytes cap set in core/src/config.ts, and its stored confidence notes record that the raw HTML exceeded 3 MB and was truncated with parity scored on the captured portion. Eleven noscript elements is what the captured portion holds. The real document may hold more, and this is a smaller version of the boundary problem we described when Googlebot reads the first two megabytes of a response and stops.
-
gymshark.com1 head, 10 body Seven of the ten sit inside a footer element. Three sit inside an anchor or button within a figure. -
webflow.com1 head, 1 body The head one holds a style element, which the specification permits in that position. The body one holds a tag manager iframe. -
en.wikipedia.org0 head, 1 body Inside the main element, which is the only case in the set sitting in main content. It holds a 1 by 1 login pixel. -
developer.mozilla.orgNone present No noscript element in the raw response or the rendered DOM. -
astro.buildNone present No noscript element in the raw response or the rendered DOM. This page scores a stored parity of 1.000.
What Lantad does with noscript, and what these counts cannot tell you
Our extractor drops noscript subtrees entirely. DROP_TAGS in core/src/extract.ts is a single set holding script, style, noscript, template, svg and iframe, and every text measurement the product takes runs through the same sink, so nothing inside a noscript element ever enters the corpus that prose parity is computed on. Parity is weighted at 0.5 in SCORE_WEIGHTS, which is half the composite, so this is not a marginal exclusion. It is the same drop list behind our note on shadow DOM text and the extractor, and it is a design decision rather than a finding.
On this evidence that decision cost these five pages nothing, because there was nothing in the elements to lose. That is a fact about five files and not a defence of the rule. A site that does put a genuine text fallback inside noscript would have that text ignored by our scanner, scored as absent, and the resulting parity figure would understate what a non-scripting reader can actually read. We would rather say that here than wait to be told. The same honesty applies to the inverse case we have already published, where text in hydration JSON scored the same as no text at all: the drop list is a blunt instrument in both directions, which is a phrase the HTML specification itself uses about noscript.
Now the limits, and they are wide. Five pages is not a sample of anything. All five were captured on a single day and a page changes between deploys. Two of the five are marketing homepages, which are not representative even of the sites they belong to. One of the five was truncated at 3 MB. And nothing here observes a crawler: this post reports what sits inside 14 noscript elements in five stored files, and it contains no evidence that any AI crawler has ever read one, ignored one, or cared either way. Notably, Google's own JavaScript SEO documentation, Last updated 2026-03-04 UTC, describes crawling, rendering and indexing as three phases with rendering deferred to a queue, and does not contain the string noscript anywhere. The element is absent from the guidance of the one crawler vendor that documents rendering in detail.
If you want to check your own pages rather than read about ours, three steps are enough and none of them needs a tool. Fetch the page without JavaScript and read what you get, which is what what GPTBot sees does for one URL. Search that response for the string noscript and look at what is inside each one: if it is an image, a pixel or an iframe, it is not a fallback for a reader, whatever it is for. Then check whether the page needs a fallback at all, because on four of these five captures it plainly does not. If your stack renders on the client, the per-stack notes for Next.js and for Shopify are the place to start, the full deduction table is on the methodology page, and the wider measurement work sits in our crawlability research. The advice we would not give is the one that shows up most often, which is to paste your content into a noscript block. On the evidence here nobody does that, and the reason nobody does that is that a page which needs it has a bigger problem than the fallback can fix, as we argued when explaining why we withhold a grade rather than printing a confident wrong one.
- noscript subtree Dropped entirely. On these five pages that discarded 13 elements and zero characters of text.
- script subtree Dropped from text, then routed to JSON-LD and hydration payload harvesting instead.
- style subtree Dropped. Includes the one 57 character CSS rule found inside a noscript element here.
- iframe subtree Dropped. A separate document, and its content is not this page's content.
- svg subtree Dropped. Icon labels and drawn text never reach the corpus.
- template subtree Dropped, and routed nowhere at all.
- alt attributes inside noscript Not read. The subtree is dropped before any attribute handler runs, so all 19 words are invisible to the scan.
- Everything else Collected as text, then classified as main content, neutral or boilerplate, with boilerplate winning.
Lantad
Published .
There is exactly one element in HTML whose entire job is to address a reader that does not execute scripts. That is noscript, and the population it was designed for in 2004 was people who had turned JavaScript off in a browser. The population that meets it now includes every program that fetches a page over HTTP, parses the markup and never starts an engine, which is a fair description of a large part of what arrives at a site as an AI crawler. So it is worth asking what real pages actually put in there.
Common questions
Do AI crawlers read the noscript tag?
The WHATWG HTML Standard specifies that a parser with scripting disabled treats noscript children as ordinary markup, so any fetch-only client can read them without doing anything special. Whether a given AI crawler does read them is not something this post measured, and Google's JavaScript SEO documentation, Last updated 2026-03-04 UTC, does not mention the element at all. Lantad's own extractor drops noscript subtrees before counting a word.
Should I put my page content inside a noscript tag for AI crawlers?
The HTML specification calls noscript a blunt instrument and advises designing the script to change the page from a scriptless page to a scripted page instead. On the five pages Lantad captured on 15 July 2026 nobody does it: the 14 noscript elements hold 11 images, one iframe, one CSS rule and zero characters of text. Serving the prose in the initial HTTP response is what all five of those pages already do, and their stored parity runs from 0.958 to 1.000.
What is actually inside a noscript element on a real website?
On these five captures, counted on 25 August 2026: 11 img elements, one Google Tag Manager iframe, one style element holding a 57 character CSS rule, and one empty element. Ten of the images carry alt text totalling 105 characters, mostly payment brand names in a footer. The eleventh is a 1 by 1 login pixel with an empty alt. Five pages is not a sample of the web.
Does rendering a page change what is inside its noscript elements?
On one of these five pages, yes. gymshark.com goes from 11 noscript elements holding 10 images in the raw HTTP response to 12 holding 3 images and one iframe after a browser has run the page, with 8 empty. Seven fallback images, carrying the alt strings Visa, Mastercard, Paypal, Apple Pay, Klarna, American Express and Afterpay, are removed by the page's own JavaScript. The other four captures are unchanged.
See what AI can read on your site
Run a free scan and get a graded report of exactly what AI crawlers can and cannot read, with ranked fixes.