Apex MenuEdge makes Dutchie menus crawlable
Apex MenuEdge is Bud Authority's edge platform for Dutchie-powered dispensary menus. It runs on Cloudflare in front of your reverse-proxied menu and rewrites each page as it is served, so search engines and AI assistants get a complete server-rendered page while shoppers keep the same live Dutchie menu and checkout.
Built and run by Bud Authority, a Dutchie Certified Partner. Available only to dispensaries we work with.
Main Street Cannabis
Open now · Pickup and delivery
House Flower
Classic Pre-Roll
Live Resin Cart
Fruit Gummies
Readable words
H1 tags
Internal links
How do I make a Dutchie menu crawlable?
Two steps. Dutchie's E-Commerce Pro loads the storefront as a sub-path of your root domain through a Cloudflare Worker. Then the HTML must carry the menu's text: in our October 2026 index, Dutchie-hosted storefronts on a store's own domain returned a median of 12 raw words to a GPTBot user-agent string. Apex MenuEdge writes that text at the Worker.
Sources: Dutchie Help Center, Cloudflare setup for E-Commerce Pro, read October 28, 2026; our Dispensary Menu Crawlability Index, October 27, 2026, three operators, reverse proxy and custom-domain setups together, requests from a non-OpenAI IP address.
Does a Dutchie iframe hurt SEO?
Dutchie says its embedded menu, launched “using an iframe,” “will be partially indexed by google.” Our index did not test Google indexing; it measured host-page text, which barely changed when the menu rendered: a median 530 raw words with a browser user-agent string, 522 rendered. Apex MenuEdge needs the menu on a sub-path first.
Sources: Dutchie Help Center, E-Commerce SEO FAQ, read October 28, 2026; Dutchie embedded menus in our crawlability index, October 27, 2026, three operators.
152 KB of HTML. Two readable words.
On October 12, 2026 we fetched nine live, reverse-proxied Dutchie storefronts in New York, New Jersey and Missouri with a GPTBot user-agent string. Every one returned a full-weight page. Almost none of it was words.
Median of 9 live Dutchie storefronts, fetched with the GPTBot user agent on October 12, 2026. H1 tags found across all 9: 0.
To be precise
Each page did carry a title, a meta description and one Store schema block with the address, coordinates and hours. What it did not carry is everything a shopper comes for: the menu, the categories, the brands, a single heading.
- Store ANY13
- Store BNY2
- Store CNY2
- Store DNY2
- Store ENY2
- Store FNJ100
- Store GNY2
- Store HMO330
- Store INY2
- MenuEdge434
Four ways to serve a Dutchie menu, and what each one shows a crawler
Dutchie's own SEO guide names them: “Dutchie offers four options to support SEO: E-Commerce with embedded menu, E-Commerce Pro + Proxy, E-Commerce with subdomain menu, or Dutchie+.” Which one you run decides whose domain holds the menu and how much of it sits in the HTML a crawler fetches. For Dutchie iframe SEO, Dutchie itself says the embedded menu is partially indexed. For a menu on your own domain, it comes down to what the HTML carries.
Embedded menu (iframe)
yourdispensary.com/menu
What Dutchie saysquick and easy to launch with just one line of code, using an iframe
Your Embedded menu will be partially indexed by google
What our index measured530 / 522host-page words: raw HTML with a browser user-agent string, then rendered in headless Chromium; median of 3 operators
Rendering barely changed the host page's word count. Our index measured page text, not Google indexing. Dutchie also says it does not explicitly support manual customization of title tags, meta descriptions and header tags.
Where MenuEdge fitsSub-path first, for MenuEdge
MenuEdge runs in a Worker that proxies the menu, so for MenuEdge the menu moves to a sub-path on your domain first.
Talk through the setup with our Dutchie SEO teamStorefront on a subdomain
store.yourdispensary.com
What Dutchie saysYour menu will be fully indexed by Google but subdomains are treated as separate sites by Google.
What our index measured67raw words with a GPTBot user-agent string, from the one Dutchie-hosted storefront on a store subdomain in our index
Indexed, by Dutchie's account, but treated by Google as a separate site from your main domain. It runs the same Dutchie storefront app as the other own-domain storefronts we measured, and its raw HTML was similarly thin.
Where MenuEdge fitsSub-path first, for MenuEdge
For MenuEdge, the menu moves to a sub-path first, so it answers on your root domain through a Worker.
Compare every menu routeSub-path through a reverse proxy
yourdispensary.com/store
What Dutchie saysmakes your Dutchie storefront menu appear as part of your root domain to search engines
The Dutchie team will then install a Cloudflare worker
What our index measured12 / 614raw words with a GPTBot user-agent string, then rendered; median of 3 Dutchie-hosted storefronts on a store's own domain
Our index could not tell a reverse proxy from a Dutchie custom-domain deployment from outside, so this group covers both, and one of the three sat on a store subdomain. All three put the URLs on the store's domain with almost no readable text in the raw HTML. One returned HTTP 403 to the GPTBot user-agent string and served a browser user-agent string.
Where MenuEdge fitsMenuEdge runs here
This is where Apex MenuEdge runs: inside that Worker, rewriting each menu page on its way out.
Headless build on Dutchie Plus
yourdispensary.com/shop/flower
What Dutchie saysa robust set of GraphQL APIs that lets you build a completely custom cannabis shopping experience
We are committed to supporting our legacy Dutchie Plus customers through the end of 2026.
What our index measured537 / 3,486raw words with a GPTBot user-agent string, then rendered; median of 3 operators
It depends on how the front end was written. In our sample the raw HTML returned to a GPTBot user-agent string carried a fraction of the words the rendered page did.
Where MenuEdge fitsFixed in the build
The front end decides what the HTML carries, so the fix lives in the build, not at the edge.
Read the Dutchie Plus migration guide
Dutchie quotes are verbatim from Dutchie's own Help Center and blog, read on October 28, 2026. We measured the word counts for our Dispensary Menu Crawlability Index (October 27, 2026) by sending a GPTBot user-agent string, a browser user-agent string and a headless Chromium render. Requests came 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. The index measured page text, not search indexing.
Dutchie storefronts on a store's own domain returned the fewest raw words
For our Dispensary Menu Crawlability Index we measured 37 menu URLs from 31 operators on October 27, 2026, each fetched with a GPTBot user-agent string and rendered in headless Chromium. Of the nine platform groups plotted, Dutchie-hosted storefronts on a store's own domain, a group that covers reverse proxy and custom-domain setups alike, returned the fewest raw words. The marks compare GPTBot-UA raw-body and browser-rendered word counts.
- Leafly, hosted marketplace3 operators2,376 / 2,529
- Sweed, own domain3 operators1,272 / 1,645
- Jane embed, own domain3 operators915 / 2,741
- Jane Roots, headless3 operators677 / 679
- Treez ecommerce, own domain2 operators, below the 3-operator minimum625.5 / 238
- Dutchie Plus, headless3 operators537 / 3,486
- Dutchie embedded menu3 operators523 / 522
- Weedmaps, hosted marketplace3 operators35 / 1,525
- Dutchie storefront on your domain3 operators, 1 of 3 returned 403 to the GPTBot user agent12 / 614
The study's named AI crawlers did not render JavaScript.
A Dutchie menu builds itself in the browser with JavaScript. In Vercel and MERJ's December 17, 2024 study, the crawlers it named from OpenAI, Anthropic, Meta, ByteDance and Perplexity did not render JavaScript, while Gemini, through Googlebot's infrastructure, and AppleBot did.
| Reader | Runs JavaScript | What it means for your menu | Source |
|---|---|---|---|
| AI crawlers named in the studyGPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, PerplexityBot, Meta-ExternalAgent, Bytespider | Runs JavaScript: No, in 2024 | Vercel and MERJ, December 17, 2024: “none of the major AI crawlers currently render JavaScript,” naming these crawlers. The same study notes that content in the initial HTML response, like JSON data, “may still be indexed.” | Vercel and MERJ, December 17, 2024 |
| Gemini and ApplebotGooglebot infrastructure, AppleBot | Runs JavaScript: Yes, in 2024 | The same study's exceptions: “Google's Gemini leverages Googlebot's infrastructure, enabling full JavaScript rendering,” and “AppleBot renders JavaScript through a browser-based crawler, similar to Googlebot.” | Vercel and MERJ, December 17, 2024 |
| Google SearchGooglebot | Runs JavaScript: Yes, later | Google queues pages for rendering: “The page may stay on this queue for a few seconds, but it can take longer than that.” It also calls server-side or pre-rendering “still a great idea.” | Google Search Central, JavaScript SEO basics |
| Voice assistantsAssistants that read one answer aloud | Runs JavaScript: Not covered | Not part of either source. A voice assistant reads one answer aloud, so we put the address, hours and categories in the page text itself. | Our practice |
One URL. Three readers. Nothing changes for your customers.
Every menu request gets one response with three layers, each written for the reader that uses it: a head every visitor shares, a server-rendered body for crawlers, and the live Dutchie menu for shoppers.

<head>
everyone
<main> server-rendered
crawlers
<div id="__next">
shoppers
one URL, one response, three readers
1. Everyone
The head: one declaration for every visitor
Title, description, canonical and the linked schema graph go into the raw HTML for every visitor, bot or human. Nothing in this layer branches on who is asking.
- A unique title for every URL
- A description written for the snippet
- A self-referencing canonical
- A linked @id schema graph
- Speakable selectors for voice
2. Crawlers
The body: an answer a machine can quote
Bots that do not run JavaScript get a server-rendered body: a real H1, an opening sentence an assistant can lift word for word, then the address, hours, categories, brands and the questions shoppers actually ask.
- One H1 per page
- An entity-first opening statement
- Address and phone as plain text
- Hours as a table
- Categories and brands as links
- Questions answered in prose
3. Shoppers
The menu: exactly the one they use today
People get the same live Dutchie menu, built in the browser exactly as before. MenuEdge only polishes what they see first, the tab title and the page heading. Cart, prices, specials and checkout never change.
- Same live inventory
- Same cart and checkout
- Same loyalty and specials
- Tab title and heading polished
Rewritten in flight, between Dutchie and the crawler.
MenuEdge runs inside the Cloudflare Worker that already proxies your menu. It does not replace Dutchie, move your menu or touch checkout. It edits the response on its way out.
- 1
Request
A shopper or a crawler asks for /stores/your-store.
- 2
Identify
The worker matches the user agent against 69 named signatures in five tiers.
- 3
Fetch
Dutchie's response comes back exactly as it does today.
- 4
Rewrite
HTMLRewriter streams that page's payload into the HTML as it passes through.
- 5
Return
Crawlers get the server-rendered page. Shoppers get the live menu, exactly as before.
Your menu worker today
// inside handleRequest
return await fetch(proxyRequest);With Apex MenuEdge
// inside handleRequest const proxiedResponse = await fetch(proxyRequest); return await injectApexMenuEdge(request, proxiedResponse, env, ctx);
In the simplest integration, that one line plus the MenuEdge module and its storage binding is the whole change, and our team does the install. In that integration, if a page has no payload or the response is not a successful HTML page, the worker returns Dutchie's original response unchanged.

Every URL is written, not templated.
Here is one store page, element by element, as a GPTBot user-agent request received it in the October 12 sample, beside an illustration built from one MenuEdge cassette. The store is a placeholder; the shapes are real.
- Title
- Dutchie: Main Street Cannabis Menu | City, ST
- MenuEdge: Main Street Cannabis Dispensary Menu, 123 Main St, City ST | Flower, Pre-Rolls, Vapes, Edibles | Pickup and Delivery 21+
- H1
- Dutchie: None in the HTML
- MenuEdge: Main Street Cannabis Dispensary, Live Menu
- Opening statement
- Dutchie: None
- MenuEdge: Main Street Cannabis is a licensed adult-use dispensary at 123 Main St, two blocks from Central Station, stocking flower, pre-rolls, vapes and edibles from licensed local brands. Adults 21 and over.
- Address and hours
- Dutchie: Inside one Store schema block
- MenuEdge: In the schema graph, as readable text, and as an hours table
- Categories and brands
- Dutchie: Built by JavaScript after the page loads
- MenuEdge: A linked list of every category and brand you stock
- Questions shoppers ask
- Dutchie: None
- MenuEdge: Answered in plain prose an assistant can quote
- Schema
- Dutchie: 1 Store block
- MenuEdge: 13 linked types in one @id graph
Five page types. Five schema treatments.
A product page is not a store page. MenuEdge classifies every URL your storefront serves and writes the entities that page type needs, all joined to one dispensary entity.
yourdispensary.com/stores/main-street
The location page AI assistants quote for address, hours and "open now" questions.
- Store
- WebPage
- BreadcrumbList
- PostalAddress
- GeoCoordinates
- OpeningHoursSpecification
- Speakable
7 linked nodes, joined by @id references to your dispensary entity.
69 crawler signatures, matched by name.
The worker knows who is asking before it decides what to send. Unknown bots fall back to a safe default.
AI answer engines
30The bots behind ChatGPT, Claude, Perplexity, Gemini and the new shopping agents.
- GPTBot
- OAI-SearchBot
- ChatGPT-User
- OpenAIAgent
- ClaudeBot
- Claude-Web
- ClaudeUser
- anthropic-ai
- PerplexityBot
- Perplexity-User
- Apple-PerplexityBot
- Google-Extended
- GoogleAgent-Mariner
- Applebot-Extended
- MetaExternalAgent
- MistralAI-User
- Cohere-AI
- DuckAssistBot
- Amazonbot
- Bytespider
- YouBot
- Kagibot
- AndiBot
- PhindBot
- NeevaBot
- AI2Bot
- Diffbot
- FirecrawlBot
- AnythingLLM
- Velocity-AI
Search engines
13Google, Bing and the long tail that still sends the map-pack and organic clicks.
- Googlebot
- Googlebot-Image
- Googlebot-Video
- Bingbot
- DuckDuckBot
- Yandex
- Baidu
- Sogou
- Naver
- Slurp
- Brave
- Mojeek
- Marginalia
Voice assistants
3Assistants that read one answer aloud.
- Alexa
- Google-Assistant
- Siri
Social previews
10The card that renders when someone shares your menu link.
- Meta-ExternalFetcher
- Twitterbot
- LinkedInBot
- Slackbot
- Discordbot
- TelegramBot
- Pinterestbot
- redditbot
SEO and data crawlers
13The tools your competitors use to study you, plus Common Crawl.
- AhrefsBot
- SemrushBot
- MJ12bot
- DotBot
- rogerbot
- SiteAuditBot
- Screaming Frog
- serpstatbot
- BLEXBot
- CCBot
- PetalBot
- SeznamBot
- Lighthouse
Check your own menu in ten seconds.
Paste your menu URL and copy the same test we ran. It runs in your own terminal, against your own site, with GPTBot's user agent. No form, no email, nothing sent to us.
01Run this in a Mac or Linux terminal
$ html=$(curl -sSfLg -A "GPTBot/1.2 (+https://openai.com/gptbot)" "https://yourdispensary.com/stores/your-store") && printf '%s' "$html" | perl -0ne 's/<head\b.*?<\/head>//s; s/<(script|style|noscript|svg|template|textarea)\b.*?<\/\1>//gs; s/<!--.*?-->//gs; my $h = () = /<h1\b/gi; s/<[^>]+>/ /g; s/&[a-z#0-9]+;/ /g; my $w = () = /\S+/g; print "H1 tags: $h\nWords: $w\n"'It prints two lines. H1 tags: 0 means no headline is in the HTML a GPTBot user-agent request receives. Words is a rough count of the text in the page body; our 9-storefront median was 2. If curl prints an error instead, the page refused or failed that request. Your terminal is not an OpenAI IP address, so a site may treat it differently from the real crawler.
Not a terminal person? Run the free audit instead: an automated scan of your site that shows its report card on screen.
Get the free auditA prerender serves a snapshot. MenuEdge also writes the page.
A prerender service hands crawlers a snapshot of the rendered page, so what they get depends on what the page renders and how the service is configured. MenuEdge writes each page's title, opening statement and schema as well as serving it.
- Menu text in the raw HTML
- Dutchie storefronts we fetched
- No
- Prerender services
- Depends
- Apex MenuEdge
- Yes
- Serves the reverse-proxied menu path
- Dutchie storefronts we fetched
- Yes
- Prerender services
- Depends
- Apex MenuEdge
- Yes
- Unique title and description per URL
- Dutchie storefronts we fetched
- Not measured
- Prerender services
- Depends
- Apex MenuEdge
- Yes
- H1 and written opening statement
- Dutchie storefronts we fetched
- No
- Prerender services
- Depends
- Apex MenuEdge
- Yes
- Linked schema graph per page type
- Dutchie storefronts we fetched
- Not measured
- Prerender services
- Depends
- Apex MenuEdge
- Yes
- Neighborhood and transit landing pages
- Dutchie storefronts we fetched
- Not measured
- Prerender services
- Depends
- Apex MenuEdge
- Yes
- Cannabis compliance review on copy
- Dutchie storefronts we fetched
- Not measured
- Prerender services
- Depends
- Apex MenuEdge
- Yes
- Live menu and checkout untouched
- Dutchie storefronts we fetched
- Yes
- Prerender services
- Depends
- Apex MenuEdge
- Yes
| Capability | Dutchie storefronts we fetched | Prerender services | Apex MenuEdge |
|---|---|---|---|
| Menu text in the raw HTML | No | Depends on setup | Yes |
| Serves the reverse-proxied menu path | Yes | Depends on setup | Yes |
| Unique title and description per URL | Not measured | Depends on setup | Yes |
| H1 and written opening statement | No | Depends on setup | Yes |
| Linked schema graph per page type | Not measured | Depends on setup | Yes |
| Neighborhood and transit landing pages | Not measured | Depends on setup | Yes |
| Cannabis compliance review on copy | Not measured | Depends on setup | Yes |
| Live menu and checkout untouched | Yes | Depends on setup | Yes |
Dutchie column: the nine reverse-proxied storefront pages we fetched with a GPTBot user-agent string on October 12, 2026; other Dutchie setups differ. Prerender services were not tested, so what they deliver depends on how each one is configured.
Engineered to fall back to the page you have today.
- Falls back to Dutchie
- In the standard integration, if a page has no payload or the response is not a successful HTML page, the worker hands back Dutchie's original response unchanged.
- Streams, never buffers
- Cloudflare's HTMLRewriter edits the page as it passes through, so the response starts flowing immediately.
- Checkout untouched
- Products, prices, specials, cart, payments and loyalty all stay on Dutchie, exactly where they are.
- Not cloaking
- Crawlers get the same store facts shoppers see. Google says rendering that produces similar content for crawlers is not cloaking.
- Isolated per client
- Each dispensary's page payloads live in storage bound to that dispensary's own worker, separate from every other client.
- Only touches menu pages
- Only successful HTML responses on your menu paths are rewritten. Images, scripts, API calls, form posts and checkout requests pass straight through.
Run by our team, end to end.
MenuEdge is not a plugin you install and forget. Our team runs it from an operator console built for this one job: every client's stores and menu paths, which crawlers asked for which pages and what they were served, every page generation run, and the versioned page payload for each URL. Every page goes through the same six steps before a crawler sees it.
1Audit
We fetch every menu URL as the crawlers do and record what they get today.
2Map
Each URL is classified: store home, category, brand, product or neighborhood.
3Research
Your store data, brands, neighborhood and the questions people ask in your market.
4Write
Every page gets its own title, opening statement, body and schema, in your voice.
5Review
Claims are checked against your store data and copy is held to your state's ad rules.
6Publish
Payloads go live at the edge, and we watch the crawler traffic from the console.
Hii NYC: 1,532 menu pages indexed by June 2026, after the May 14, 2026 MenuEdge launch
menu pages indexed after the Apex MenuEdge launch, by June 2026, after a May 14, 2026 launch
Hii NYC runs two stores in Williamsburg and Bay Ridge, Brooklyn. We rebuilt hiinyc.com on Next.js in April 2026, launched Apex MenuEdge on its menu on May 14, 2026, and by June 1,532 menu pages were in Google's index.
Source: verified Q2 2026 quarterly review, July 8, 2026.
Read the Hii NYC case fileWho Apex MenuEdge is for
MenuEdge is built for dispensaries whose Dutchie menu runs through a reverse proxy on their own domain. If yours is served another way, the first step is a different one, and each is covered below.
A direct fit
Single stores on Dutchie E-Commerce Pro
The menu already answers on a sub-path of your domain through a Cloudflare Worker, so MenuEdge goes into the Worker you have.
Multi-location groups and MSOs
One Dutchie store per location, each with its own store home, category, brand, product and neighborhood pages, written for that location so no two share copy.
Owners who want it run for them
MenuEdge is not sold as software. We deploy and run it for dispensaries that work with us on SEO, AEO and GEO.
Starts with a different step
On the embedded iframe or a subdomain storefront
Move the menu to a sub-path on your own domain first, then MenuEdge goes into that Worker.
Dutchie SEO servicesOn legacy Dutchie Plus
Dutchie says it is committed to supporting legacy Plus customers through the end of 2026. Talk to us about migration timing.
Dutchie Plus migration guideOn Jane, Treez, Sweed or another menu platform
MenuEdge is built for Dutchie. Start with what your platform hands a crawler today.
Dispensary menu platforms comparedOn a custom headless front end
The fix belongs in the build: product and category pages rendered on the server.
Technical cannabis SEO
What dispensary owners ask us about Apex MenuEdge
What is Apex MenuEdge?
Apex MenuEdge is Bud Authority's edge platform for Dutchie-powered dispensary menus. It runs on Cloudflare in front of your reverse-proxied menu and rewrites each page as it is served, so search engines, AI assistants and voice assistants receive a complete server-rendered page with your address, hours, categories and brands. Shoppers keep the same live Dutchie menu and checkout.
Why might ChatGPT or Perplexity miss my Dutchie menu?
The menu is built by JavaScript in the shopper's browser. In a December 17, 2024 study, Vercel and MERJ found that the crawlers they named from OpenAI, Anthropic, Meta, ByteDance and Perplexity did not render JavaScript. On October 12, 2026 we fetched nine reverse-proxied Dutchie storefronts with a GPTBot user-agent string: the median body carried two readable words.
Do I have to change my menu, my POS or my checkout?
No. MenuEdge works on the response after Dutchie sends it. Your products, prices, specials, cart and checkout stay exactly where they are, and the live menu still loads in the shopper's browser. MenuEdge is added to the Cloudflare Worker that already proxies your menu, and our team does the install.
Is serving crawlers a rendered page considered cloaking?
Not when the content matches. Crawlers receive a server-rendered version of the same store a shopper sees, with the same address, hours, categories and brands. Google's dynamic rendering guide says: "As long as your dynamic rendering produces similar content, Googlebot won't view dynamic rendering as cloaking." The head tags and schema graph are identical for every visitor.
Will MenuEdge slow my site down or break the menu?
It is built to step aside. The rewrite streams through Cloudflare's HTMLRewriter instead of buffering the page. In the standard integration, if a page has no payload or the response is not a successful HTML page, the worker returns Dutchie's original response unchanged. Images, scripts, API calls and checkout requests are never rewritten.
Does MenuEdge work with a Dutchie iframe or a subdomain menu?
Not directly. MenuEdge runs in the Cloudflare Worker that reverse-proxies a Dutchie menu onto your own domain, the setup Dutchie calls E-Commerce Pro + Proxy. A store on the embedded iframe or a subdomain storefront moves to that sub-path first. A Dutchie+ headless build writes its own HTML, so its fix lives in the front end.
How do I get Apex MenuEdge?
MenuEdge is not sold as software. It is deployed and run by Bud Authority for dispensaries that work with us on SEO, AEO and GEO, because the value is in the store research, compliance review and brand-voice writing behind every page. Start with the free audit, an automated scan of your site that shows its report card on screen.
Keep reading
- Dutchie SEO servicesThe full playbook for ranking a Dutchie-powered dispensary, menu included.
- Dispensary Menu Crawlability IndexOur 37-URL measurement of what a GPTBot user-agent string and a browser got from 11 menu platform groups.
- Dutchie vs Treez vs JaneIframe, subdomain, sub-path or headless: what each vendor documents, compared.
- Dutchie Plus migrationMigration options for legacy Dutchie Plus storefronts.
- Technical cannabis SEORendering, crawl paths, schema and speed across the whole site.
- Our Dutchie partnershipHow we work with Dutchie as a Certified Partner.
Be the answer.
Find out what search engines and AI crawlers get from your site today. The free audit is an automated scan that shows its report card on screen, and it is where every MenuEdge engagement starts.
Questions first? service@budauthority.com. Apex MenuEdge is deployed and run by Bud Authority for dispensaries on Dutchie. It is not sold as standalone software.
