Dispensary Menu Crawlability Index 2026
Dispensary menu crawlability, measured: we fetched 37 menu URLs on 11 platform groups as GPTBot, a browser and a renderer. Read the medians and the method.
Get a Free Audit for This Service// Page Stats
8
Sections
2K
Words
8 min
Read Time
The Dispensary Menu Crawlability Index is a first-party measurement by Bud Authority: on October 27, 2026, we fetched 37 menu URLs from 31 operators across 11 platform groups. Marketplace pages on dutchie.com and iheartjane.com returned HTTP 403 to both a GPTBot and a desktop browser user agent, Dutchie-hosted storefronts on store domains sent a median 12 raw words, and only Leafly carried JSON-LD Product, Offer or AggregateOffer nodes in raw HTML at the median. The operator's test: are your menu text and product data in the raw server response on your own domain?
By Mark Wallace, Co-Founder & Chief Growth Architect at Bud Authority.
// On This Page
How we measured 37 menu URLs, and the limits of the sample
Each menu URL got one measurement from each of three methods:
- Raw HTML requested with the GPTBot user-agent string, which is what a crawler that does not run JavaScript receives.
- Raw HTML requested with a desktop browser user agent, which separates a block aimed at GPTBot from a page that sends little text to anyone.
- The rendered page, loaded in headless Chromium after its scripts ran.
For every fetch we counted the readable words in the page body, after removing scripts and styles, and the JSON-LD nodes typed Product, Offer or AggregateOffer, duplicates included. Word counts include header links and footer text, so they measure how much text a page sends, not how many products it lists. A menu inside an iframe is a separate document, so its text is not in the host page's count.
Every reading is a median across the URLs in one platform group, never an average. Raw and rendered medians are taken separately, so within one group they can come from different URLs: read them as two readings, not as one page before and after.
Operators are anonymous. We name the platforms because the platforms are what the index measures, but no dispensary or store is named, and several menus from one business share one operator label.
The sample has limits:
- It is small and was chosen by web search and homepage inspection, not drawn at random.
- Requests used the GPTBot user-agent string from a non-OpenAI IP address, so a 403 shows how a site treats that user agent from an unverified source and may not match what OpenAI's crawler receives.
- No Dispense (AIQ Ecommerce) storefront was identified in the sample, and Treez ecommerce reached 2 operators, below the 3-operator minimum the index uses for a platform reading. Neither platform has a reading in the table.
- We did not evaluate robots.txt, check search engine indexing, or test whether any AI product cites these pages.
- A single run reflects one moment. Menus, age gates and store pickers change what a page returns.
Every figure here comes from public page fetches. Client accounts feed a different study, our state of dispensary search report, which reads Search Console and AI answer data from the client book.
Median readable words by menu platform, raw HTML against rendered page
Each row gives the URLs and distinct operators behind its medians. The last column counts raw fetches that returned HTTP 403 to the GPTBot user agent.
| Platform group | URLs | Operators | Raw words, GPTBot UA | Raw words, browser UA | Rendered words | JSON-LD Product, Offer or AggregateOffer nodes (duplicates included), raw / rendered | HTTP 403 to GPTBot UA |
|---|---|---|---|---|---|---|---|
| Dutchie (dutchie.com hosted) | 4 | 4 | blocked (403 page) | blocked (403 page) | challenge or blank page | 0 / 0 (block page) | 4 of 4 |
| Dutchie embedded menu, iframe (own domain) | 3 | 3 | 523 | 530 | 522 | 0 / 0 | 0 of 3 |
| Dutchie Plus / headless (own domain) | 3 | 3 | 537 | 537 | 3,486 | 0 / 0 | 0 of 3 |
| Dutchie-hosted storefront on the store's own domain (reverse proxy or custom domain) | 3 | 3 | 12 | 13 | 614 | 0 / 0 | 1 of 3 |
| Jane (iheartjane.com hosted) | 3 | 3 | blocked (403 page) | blocked (403 page) | challenge or blank page | 0 / 0 (block page) | 3 of 3 |
| Jane embed (own domain) | 3 | 3 | 915 | 936 | 2,741 | 0 / 0 | 0 of 3 |
| Jane Roots / headless Jane (own domain) | 3 | 3 | 677 | 815 | 679 | 0 / 0 | 0 of 3 |
| Sweed (own domain) | 5 | 3 | 1,272 | 1,282 | 1,645 | 0 / 0 | 0 of 5 |
| Weedmaps (weedmaps.com hosted) | 3 | 3 | 35 | 37 | 1,525 | 0 / 1 | 0 of 3 |
| Leafly (leafly.com hosted) | 3 | 3 | 2,376 | 2,385 | 2,529 | 159 / 159 | 0 of 3 |
Raw fetches to the Dutchie-hosted and Jane-hosted marketplace pages returned HTTP 403 to both the GPTBot and the browser user agent, so that block is not user-agent selective, and the headless browser that rendered them was also challenged or shown a blank page. Those two rows describe a block page, not a menu.
The Dutchie embedded menu row counts the store page around the frame. The menu itself sits in the iframe, so those word counts are the host site's own copy, not menu text.
Sweed's 5 URLs came from 3 operators, so at least one operator contributed more than one URL and weighs more in that median than the others.
How each Dutchie setup answered a GPTBot fetch
The Dutchie rows differ by setup more than by vendor.
- The dutchie.com marketplace page refused the browser user agent as well, so it shows nothing about how Dutchie treats AI crawlers in particular.
- The embedded menu on a store's own site is an iframe, and Dutchie's support documentation says “Your Embedded menu will be partially indexed by google.” Our build method describes an embedded Dutchie iframe as not same-origin: the menu text belongs to Dutchie's document, not to your page.
- Dutchie Plus and headless builds carried no JSON-LD Product, Offer or AggregateOffer nodes at the median, raw or rendered. A median of zero does not rule out markup on an individual URL.
- Dutchie-hosted storefronts served from a store domain sent the least raw text of any own-domain group, and they were the only own-domain group with a 403 to the GPTBot user agent.
That last result matches an earlier check of our own: when we fetched nine live Dutchie storefronts as GPTBot on October 12, 2026, the median page body carried two words of text and none had an H1.
None of this settles whether ChatGPT can read Dutchie menus. OpenAI's crawler overview states that “OAI-SearchBot is used to surface websites in search results in ChatGPT’s search features.” The index sent the GPTBot string from a non-OpenAI IP address, so it shows what a crawler announcing itself as GPTBot, and running no JavaScript, was sent.
Disclosure: Bud Authority is a Dutchie Certified Partner. That status did not change how the Dutchie rows were fetched or counted, and the index ranks no platform.
Where product data reached the raw HTML and where it did not
Leafly was the only platform group whose raw HTML carried JSON-LD Product, Offer or AggregateOffer nodes at the median, from 3 URLs and 3 operators.
Weedmaps hosted pages showed the opposite pattern in this sample: a median of 35 raw words with a GPTBot user agent and 1,525 after rendering.
The gap between raw and rendered matters because crawlers differ. Vercel's study with MERJ, The rise of the AI crawler, reported as of its publication: “The results consistently show that none of the major AI crawlers currently render JavaScript.” The same study named an exception: “AppleBot renders JavaScript through a browser-based crawler, similar to Googlebot.” Google does render, and its JavaScript SEO basics page sets the limit: “If the content isn't visible in the rendered HTML, Google won't be able to index it.”
What each reading means for a dispensary operator
A menu on a hosted marketplace page.
Both marketplaces sent our fetches a block page, so the index cannot say what they serve a verified crawler. The menu pages you can test and change are the ones on your own domain.
An embedded iframe menu.
A crawler can read the page around the frame, but the menu inside it is Dutchie's document. Fetch your menu URL without JavaScript and search the response for a product you stock. If the name is missing, that response does not carry the product, and a crawler that skips JavaScript could not read it there.
A Dutchie storefront served from your own domain.
For that setup we deploy and run Apex MenuEdge for dispensaries that work with us on SEO, AEO and GEO, Dutchie SEO included, so crawlers receive a server-rendered page while shoppers keep the same live Dutchie menu and checkout, and our client portfolio includes a case file on an Apex MenuEdge launch.
Product data a crawler can read without JavaScript.
JSON-LD Product, Offer or AggregateOffer nodes have to be in the server response, and in this sample the only group that shipped them there at the median was a marketplace, not a store's site. For your own menu pages we offer dispensary web design and CRO.
To see where your own site stands, request the dispensary audit. It runs an automated scan and shows the report card on screen.
Dataset and download
The anonymised dataset is published as dispensary-menu-crawlability-index-2026-10-27.csv: 37 rows, one per measured URL, with operators as OP labels and no URLs. Its columns are operator, platform_group, checked, gptbot_raw_status, gptbot_raw_words, gptbot_raw_h1, gptbot_raw_jsonld_product_offer_nodes, browser_raw_status, browser_raw_words, rendered_words, rendered_h1, rendered_jsonld_product_offer_nodes and age_gate_flag. The two jsonld columns count JSON-LD Product, Offer or AggregateOffer nodes, duplicates included.
How to cite the index
Cite this as: Mark Wallace, Bud Authority, Dispensary Menu Crawlability Index, measured October 27, 2026, budauthority.com/research/dispensary-menu-crawlability-index. When you quote a reading, give the platform group with its URL and operator counts, and keep the non-OpenAI IP caveat beside any 403.
Frequently asked questions
How do I make a Dutchie iframe menu crawlable?
Take the menu out of the iframe. Dutchie documents a custom domain as the alternative to the iframe, which it calls “a custom URL, often referred to as a subdomain.” In this index, Dutchie-hosted storefronts on store domains, by custom domain or proxy, still sent almost no raw text before JavaScript ran, so check the new URL's raw response as well.
Why is my dispensary not appearing in ChatGPT answers?
One cause OpenAI documents is a robots.txt opt-out: “Sites that are opted out of OAI-SearchBot will not be shown in ChatGPT search answers, though can still appear as navigational links.” The Vercel and MERJ study above adds a second check: the major AI crawlers it measured did not render JavaScript, so menu text that appears only after scripts run was out of their reach.
Continue Exploring
State of Dispensary Search 2026: Client Data and a Menu Crawl Sample
State of dispensary search 2026: AI engines named the client in 1,843 of 3,275 runs and menu pages drew 12.1% of Google clicks. Read the tables and method.
The truth rules behind Bud Authority's SEO methodology
The Bud Authority SEO methodology is a set of truth rules: nothing fabricated, pages only where demand exists, every claim sourced. Request the free audit.
Cannabis Advertising Restrictions and What SEO Still Reaches
Cannabis advertising restrictions and SEO: Meta and Google bar THC ads but keep CBD exceptions, and states add audience rules. Run a free audit of your site.
Cannabis Backlink Building: Start by Auditing What You Have
Cannabis backlink audit: keep editorial links, qualify paid ones and disavow only when Google's test is met. See the keep or cut calls, then get a free audit.
Cannabis Competitor Analysis: Start With the Rivals Google Shows
Cannabis competitor analysis starts with the rivals Google shows for your queries. Compare local signals, content, links and crawler reads. Get a free audit.
How to Run a Cannabis Content Audit
Cannabis content audit method: score every indexed page on Search Console and GA4 data, sort it into seven actions, then run our free automated audit.
// deploy
Ready to Deploy This Protocol?
Start with a comprehensive audit. We'll map every opportunity and build your custom growth protocol.
> [ INITIATE AUDIT ]


