# Pack 2 · menu-qr-fix

Drafted Wed Oct 21, 2026 (PT) for json's local Claude crew. Hand-off only: nothing has been built, deployed, posted, emailed or created in Stripe.
Source research: `/workspace/jkca-stack/product-gaps/NEEDS-2026-10-21.md` (#2). Claims are re-checked in `FACTS.md`. IDs like [Q1] point there.

House rules: no em dashes, straight quotes, US spelling, links in the first reply on X, only studio figure "about fifty live sites", no testimonials, no deal copy, pills and buttons ALL CAPS with no "!", and no vendor names in pills or headlines.

---

## 1. The problem in plain words

A restaurant prints menus, table tents and window cards with a QR code from a "free" generator. Most of those codes don't hold the menu address at all. They hold a short link on the generator's own domain, which then forwards to the menu. When the free trial ends, the generator stops forwarding, and every printed code opens a "subscribe to continue" page instead of the menu [Q1].

Scanworthy, a QR company, says most free trials run 7 or 14 days, and that the owner's choices are then to pay the subscription or reprint [Q1]. Internal context only. Don't quote it in public copy.

The fix is ownership. A static QR code holds the address directly. If that address is on the restaurant's own domain (for example theirsite.com/menu), the owner controls where it goes. To change the menu, they change the redirect, not the print.

The honest limit: a code that already holds the generator's domain can't be rescued by anyone but that generator. Scanworthy says the same: a server-side redirect only helps when the code held a URL on a domain you control [Q1]. For those, the answer is new codes, on stickers or a reprint.

Who it hits: restaurants, cafés, bars, salons, food trucks, and anyone with printed menus, flyers or window cards. Locally (Main Street Seal Beach, Belmont Shore) this is **unsourced**. The research found the national pattern, not a local complaint. Don't claim local demand in copy.

---

## 2. Offer ladder and prices

| Step | What | Price | Where |
|---|---|---|---|
| 1 | Free note: why your menu QR died, and how to own the next one | Free | jkca.studio/notes/menu-qr-code-stopped-working/ |
| 2 | Menu QR fix: redirect on your own domain, plus static QR files, for up to 10 codes | $49 | jkca.studio/services/menu-qr/ |

Notes for json:
- $49 covers one domain and up to 10 codes (the research's proposal). More codes: json to price. Don't print a number until he does.
- The research floated $99 with print-ready table tents. That's **not** in this pack's Stripe list. It's a json decision. Until then, tents and stickers are "quoted" in the not-included list.
- No paid guide for this one. The note is the funnel.

---

## 3. Free note (full draft)

Same shape as the live notes (answer-first lede, byline, short H2s, one table, a "Last checked" line, FAQ).

- Slug: `/notes/menu-qr-code-stopped-working/`
- H1: **Why your menu QR code stopped working, and how to own the next one**
- Index blurb: Many "free" QR codes point at the generator's own link, not your menu, so they stop when the trial ends. A static code on your own domain keeps working as long as you keep the domain.

```markdown
# Why your menu QR code stopped working, and how to own the next one

Published October 2026 · Json Knepper

If your printed menu QR code now opens a "subscribe to continue" page, the code itself is fine. It was never pointing at your menu. It points at a short link the QR company owns, and the company switched that link off when the free trial ended. The next code should point at an address on your own domain, so you're the one who decides where it goes.

## What actually happened

There are two kinds of QR code.

- A static code holds the final address itself. Nothing sits in the middle.
- A "dynamic" code holds a short link on the QR company's domain. When someone scans it, the company forwards them to your menu. That's what lets you change the menu without reprinting, and it's also why the company can stop it.

Scanworthy, a QR company, says most QR platforms offer a 7-day or 14-day free trial of dynamic codes. When the trial ends, the forwarding stops, and every printed copy stops with it.

## Can the old code be saved?

Check what's inside it first. Point your phone camera at the code and read the address it shows before you tap.

| The address starts with | What it means | What to do |
|---|---|---|
| Your own domain (yoursite.com/...) | You control it | Set a redirect on your domain. The print works again. |
| The QR company's domain | They control it | Only they can turn it back on. Plan new codes. |
| Your menu or ordering page directly | It's static | It should still work. If not, the page moved. Put it back or redirect it. |

If it's the QR company's domain, paying them works, but only for as long as you keep paying. New codes on your own domain end that.

## How to own the next one

1. Pick a short address on your own domain, like yoursite.com/menu. Keep it short and lowercase. It also goes under the code in print, so people can type it.
2. Make that address a redirect to wherever your menu lives today: a page on your site, a PDF, or your ordering system.
3. Make a static QR code that holds yoursite.com/menu, and nothing else.
4. Print it, then scan it with an iPhone and an Android phone before the full run.

When the menu changes, you change the redirect. The printed code never changes.

Use a temporary redirect (302) for this, not a permanent one (301). The HTTP standard lets browsers and phones cache a 301 on their own, so a change might not reach someone who scanned before. A 302 doesn't carry that rule, so a change reaches people sooner.

## Print it so it scans

- Leave a clear margin around the code. The QR standard asks for a quiet zone four modules wide (a module is one small square) on every side.
- Dark code on a light background. No gradients, and no light-on-dark.
- Skip the logo in the middle. The code can carry one, but it costs scanning room.
- Print the address under the code in plain text.
- Test the printed proof, not the screen version, at arm's length and in dim light.

Last checked October 21, 2026.

### Why did my QR code stop working?
Most often because it was a dynamic code from a free trial. It held the QR company's short link, not your menu, and the company stopped forwarding that link when the trial ended.

### Can I fix a QR code that's already printed?
Only if the address inside it is on a domain you control. Scan it and read the address. If it's the QR company's domain, only they can turn it back on.

### What's the difference between a static and a dynamic QR code?
A static code holds your address directly. A dynamic code holds someone else's short link, which forwards to your address. A static code that points at a redirect on your own domain gives you both: it doesn't expire on its own, and you can still change where it goes.

### Will a static QR code ever expire?
The code itself doesn't expire. It keeps working as long as the address inside it works, which means as long as you keep your domain renewed and the redirect in place.

### Should the redirect be a 301 or a 302?
A 302, for a menu that changes. The HTTP standard allows a 301 to be cached by browsers and phones, so a later change might not reach everyone.

### Do I need a paid QR service?
Not for a menu. A static code plus a redirect on your own domain does the job. The paid features you'd give up are things like scan counts.
```

---

## 4. Paid guide

None for this offer (per the brief). The note is the funnel to the $49 fix.

---

## 5. Service scope: Menu QR fix ($49)

### Included (fixed)
- [ ] Decode each old printed code and tell the owner which ones can be rescued (their domain) and which can't (the generator's domain).
- [ ] One domain, up to 10 short paths (for example /menu, /drinks, /brunch, /happy-hour, /wine).
- [ ] Each path set up as a 302 redirect on Cloudflare (steps in section 6a) or in the site's `_redirects` file if it's a JKCA site on Cloudflare (section 6b).
- [ ] Rescue redirects for any old code that holds the owner's own domain.
- [ ] One static QR code per path, made to the print spec in section 6c.
- [ ] Files per code: SVG (vector master), PDF (vector, for the print shop) and PNG (300 ppi at the final print size), plus a contact sheet with every code labeled.
- [ ] Scan tests on one iPhone and one Android phone, from a printed proof.
- [ ] A one-page "how to change your menu link" card for the owner, plus a JKCA-held note of every path and target.
- [ ] One round of target changes within 14 days of handoff (json to confirm the window).

### Not included
- Printing, stickers, table tents or reprints (quoted separately).
- Bringing back codes that hold the generator's domain. Not possible from our side.
- Moving the domain's DNS to Cloudflare if it means rebuilding a complicated record set, or anything that risks email. A simple nameserver move with every record copied is included. Anything messier is quoted.
- Building or redesigning the menu page or PDF itself.
- Scan analytics or dashboards.
- More than 10 codes (json to price).
- Ongoing changes after the window (that's care, from $69 a month, or a small fixed fee json sets).

### Intake questions (one per screen)
1. What's your business name and website address?
2. Where do you sign in to manage your domain? (registrar name, or "not sure")
3. Is your domain on Cloudflare already? (Yes / No / Not sure)
4. Who built your website, and where is it hosted?
5. How many different QR codes do you need? List what each one opens (dinner menu, drinks, brunch, ordering, reviews).
6. Where does each menu live today? (a link, a PDF, an ordering system)
7. Do you have old printed codes? Upload a clear photo of each one.
8. What are they printed on? (menus, table tents, window, flyers, packaging)
9. About how large will the code print? (rough inches are fine)
10. Any brand colors or a logo for the print files?
11. Who should get the files, and who will change the links later?

---

## 6. Crew setup (exact)

### 6a. Cloudflare redirect (domain on Cloudflare DNS)

Requirements, from Cloudflare's docs: Single Redirects and Bulk Redirects both need the hostname's traffic proxied through Cloudflare (orange cloud) [Q3]. The Free plan allows 10 Single Redirect rules per zone, and 15 Bulk Redirect rules, 5 lists and 10,000 URL redirects per account [Q3].

**Pick the hostname**
- If the site's apex and www are already proxied on Cloudflare (most JKCA sites), use `theirsite.com/menu`.
- If the site is hosted somewhere that wants DNS-only records, don't flip the main site's proxy. Use `go.theirsite.com/menu` instead. When you deploy the rule, Cloudflare offers to create a proxied DNS record for a hostname that doesn't have one. Accept it. It gets a `rules` tag and the comment "Created during Cloudflare Rules deployment process for <RULE_NAME>" [Q3].

**Default: Bulk Redirects (one list, up to 10 codes, doesn't use up the zone's 10 single rules)** [Q4]
1. Cloudflare dashboard > the client's account > **Bulk redirects** (or zone > **Rules** > **Settings** > **Bulk Redirects** tab).
2. Under Bulk Redirect Lists, select **Create Bulk Redirect List**. Name: `qr-<client-slug>`. Description: `Menu QR codes, JKCA, <date>`. Select **Next**.
3. Select **Or, manually add URL redirects**, then add one row per code:
   - Source URL: `theirsite.com/menu` (no scheme, so it matches both http and https; no query string, which sources can't have)
   - Target URL: `https://theirsite.com/menus/dinner/` (or the PDF or ordering link)
   - Status: `302`
   - Edit parameters: Preserve query string **off**, Subpath matching **off**, Include subdomains **off**, Preserve path suffix **off**.
   - Also add `theirsite.com/menu/` (trailing slash) to the same target, unless the site already normalizes it.
4. **Next**, review, **Next**, then **Continue to Redirect Rules**.
5. Rule name: `qr-<client-slug>`. Select the list. **Save and Deploy**. Accept the proxied-record prompt only for a `go.` host.
6. Test from the box: `curl -sI https://theirsite.com/menu` should return `HTTP/2 302` and `location: <target>`. Repeat for every row, both http and https, with and without the trailing slash.
7. Use Cloudflare Trace (Rules > Trace) if a row doesn't fire.

**Alternative: one Single Redirect per code (1 to 3 codes, zone has free rule slots)**
1. Zone > **Rules** > **Overview** > **Create rule** > **Redirect Rule**.
2. Rule name: `qr menu`.
3. **Custom filter expression**: `(http.host in {"theirsite.com" "www.theirsite.com"} and http.request.uri.path in {"/menu" "/menu/"})`
4. Then: Type **Static**, URL `https://theirsite.com/menus/dinner/`, Status code **302**, Preserve query string **off**.
5. **Deploy**. Test with curl as above.

**Changing a menu later**: edit the Target URL on that list row (or rule). Leave the source alone. Re-test with curl.

### 6b. JKCA site on Cloudflare Workers or Pages (repo-managed)
Add lines to `public/_redirects` [Q5]:
```txt
# Menu QR codes (static codes, do not rename the left side)
/menu        /menus/dinner/   302
/menu/       /menus/dinner/   302
/drinks      /menus/drinks/   302
/drinks/     /menus/drinks/   302
```
- No code means 302, which is the default, but write it out anyway [Q5].
- Redirects in `_redirects` don't apply to requests your Worker code (or Pages Functions) serves. If the site routes `/menu` through code, add the redirect there or use 6a [Q5].
- Static redirects go above dynamic ones. The file allows 2,000 static plus 100 dynamic [Q5].

Why 302 and not 301: RFC 9110 says a 301 (and a 308) response is "heuristically cacheable", so phones and browsers can hold on to the old target. 302 has no such line [Q6]. A menu is meant to change.

### 6c. Print-ready QR spec

Standards-backed (Denso Wave, the QR code's inventor, and ISO/IEC 18004) [Q7]:
- Quiet zone: 4 modules on every side, with nothing printed in it.
- Error correction levels: L about 7%, M 15%, Q 25%, H 30% of the data recoverable.
- More data means more modules. Keep the encoded URL short.

JKCA house spec (our choices, not a standard; Critic may tune them):
- Encode exactly `https://theirsite.com/menu`. No tracking parameters, no www, lowercase.
- Error correction **M**. Use **Q** only if the code sits on a textured or glossy surface. No center logo.
- Black (#000) or the brand's darkest ink on white or cream. Never inverted, no gradients, no transparency over photos.
- Minimum printed width, quiet zone included: 1 in (25 mm) on menus and table tents, 2 in (50 mm) on windows and posters. Scan-test any size from the real proof.
- The URL under the code in plain text, at 9 pt or larger: `theirsite.com/menu`.
- An optional label pill above: `SCAN FOR MENU` (all caps, no "!").
- Print shop files: vector PDF with 0.125 in bleed on the artboard (not on the code), plus SVG. PNG at 300 ppi at the final size for digital use.
- File names: `<client>-qr-menu.svg`, `.pdf`, `.png`. A contact sheet: `<client>-qr-sheet.pdf`.

Generate and check on the box:
```bash
python3 -m venv .qr && . .qr/bin/activate && pip install segno   # once (tested on the box 2026-10-21: segno writes SVG, PDF and PNG)
# zbarimg for the check: macOS `brew install zbar`, Debian/Ubuntu `sudo apt-get install zbar-tools`
python3 - <<'PY'
import segno
for slug in ["menu","drinks"]:
    q = segno.make(f"https://theirsite.com/{slug}", error="m", micro=False)
    q.save(f"client-qr-{slug}.svg", border=4, scale=10, dark="#000000", light="#ffffff")
    q.save(f"client-qr-{slug}.pdf", border=4, scale=10)
    q.save(f"client-qr-{slug}.png", border=4, scale=20)
PY
zbarimg client-qr-menu.png   # must print exactly: QR-Code:https://theirsite.com/menu
```
Then place the codes in the Card Lab or tent template, export the proof, print it, and scan it with an iPhone and an Android phone at arm's length and in dim light. Record pass or fail per code on the contact sheet.

---

## 7. Landing / section copy: /services/menu-qr/

§E order. Pigment drift in the hero only. One primary CTA per viewport.

**Hero**
- Eyebrow pill: `MENU QR CODES`
- H1 (8 words): **Print your menu QR once, and keep it**
- Subline: For restaurants and cafés whose printed codes stopped opening the menu.
- Primary button: `FIX MY MENU QR` (goes to the Kindform intake, not to checkout)
- Secondary link: `Why codes stop working` (to the note)

**Proof strip**: client logos only if json approves, or "We look after about fifty live sites from Seal Beach."

**Problem (3 lines)**
> Many free QR codes point at the QR company's link, not your menu.
> When the trial ends, every printed code opens a payment page.
> The code was never yours. The next one should be.

**Features (3, each with its proof)**
1. **Your own address inside the code.** The code holds yoursite.com/menu, and nothing else. Proof: scan it and read the address.
2. **Change the menu, not the print.** The redirect points wherever your menu lives this season. Proof: the one-page "change your link" card you keep.
3. **Files your printer can use.** Vector PDF and SVG, scan-tested from a real proof on two phones. Proof: the contact sheet with pass marks.

**Attributed line**: "Codes on the QR company's domain can only be turned back on by that company. So we check yours first, and tell you straight."

**How it works (3 steps)**
1. Send a photo of your old codes and tell us where the menu lives.
2. We read your codes, tell you which can be saved, and send the $49 link.
3. You scan the proof, then print.

**Pricing**
| FREE NOTE | THE FIX (featured) |
|---|---|
| Free | $49 |
| How to tell if your code can be saved, and how to own the next one | Up to 10 codes on your own domain, print files, scan-tested |
| `READ THE NOTE` | `FIX MY MENU QR` |

**Close**
- Doubt-killer: "If your old codes point at the QR company's domain, we'll tell you before you pay for anything they can't fix."
- Button: `FIX MY MENU QR` (to intake, same as the hero)
- Link: `TALK TO A HUMAN →`

---

## 8. Stripe (for the crew to create later; not created)

| Product name | Price | Type | Description |
|---|---|---|---|
| Menu QR fix (up to 10 codes) | $49.00 USD | One-time | "JKCA Studio sets short redirects on your own domain and makes static QR codes that point to them, with print-ready SVG, PDF and PNG files, scan-tested on two phones. Up to 10 codes. Printing not included." |

Flow: no checkout on the page. Every `FIX MY MENU QR` button goes to the Kindform intake. After we've read the old codes and told the owner which can be saved, we send this Payment Link. Custom text near Pay: "Thanks for the photos. After you pay, we set up your redirects and send the print files." Statement descriptor `JKCA STUDIO`.

---

## 9. X drafts for @jkcastudio

**Post 1**
```text
If your printed menu QR suddenly opens a "subscribe" page, the code isn't broken.

It never held your menu's address. It held the QR company's short link, and they turned it off when the trial ended.

Scan it and read the address before you tap. That tells you if it can be saved.
```
First reply: `What to check, and how to own the next one: https://jkca.studio/notes/menu-qr-code-stopped-working/`
Card line: `Your menu QR, on your own domain`

**Post 2**
```text
A small detail for menu QR codes: use a 302 redirect, not a 301.

The HTTP standard lets phones and browsers cache a 301 on their own. A menu changes with the season, and you want every scan to land on this week's.
```
First reply: `The full note: https://jkca.studio/notes/menu-qr-code-stopped-working/`
Card line: `302 for menus that change`

**Post 3**
```text
We set up menu QR codes that point at the restaurant's own domain.

Static code, short address like yoursite.com/menu, a redirect you can change any time, and print files tested from a real proof on two phones. $49 for up to 10 codes.

If your old codes point at the QR company, we'll say so first.
```
First reply: `https://jkca.studio/services/menu-qr/`
Card line: `Print once, keep it`

---

## 10. SEO

- Note `<title>`: `Why your menu QR code stopped working (and how to own the next one) | JKCA Studio`
- Note meta: `Many free QR codes point at the generator's link, so they die when the trial ends. How to check yours and make a static code on your own domain instead.`
- Service `<title>`: `Menu QR code fix on your own domain, $49 | JKCA Studio`
- Service meta: `Static QR codes that point at a redirect on your own domain, so a printed menu doesn't need reprinting when the menu changes. Up to 10 codes, print-ready files, $49.`
- FAQPage JSON-LD for the 6 FAQs.

---

## 11. Ship steps for the Claude crew

1. Read PACK.md and FACTS.md. Re-open Q1, Q3 to Q5, and Q7 (the qrcode.com spec, in a browser) before pasting.
2. Note: add `menu-qr-code-stopped-working` to the notes collection from section 3. Set the publish date to the ship date.
3. Service page `/services/menu-qr/` from section 7. Link it from /services/. Intake in Kindform with the 11 questions. Every CTA goes to intake. No checkout on the page.
4. Stripe: draft the one product in test mode. json does live.
5. Keep the setup runbook (section 6) in the jkca toolkit as `runbooks/menu-qr.md` so every job runs the same way. Include the segno snippet and the curl checks.
6. Optional demo: `https://jkca.studio/menu-demo` returns 404 today. Don't link it or print a code for it unless you build it. If you do, give it a 302 to the note, confirm with `curl -sI` that it returns 302, then make the demo code. No fake client names.
7. Run the page at 390, 768 and 1440, plus axe. Scan the demo code from a laptop screen with two phones.
8. Open a PR. No deploy. Critic, then json.

---

## Ship gate

- [ ] Critic pass on the note, the service page and the runbook.
- [ ] json sign-off on: $49 and its 10-code cap, the 14-day change window, the price for codes past 10 (or keep "ask"), and whether tents or stickers get a product.
- [ ] No Scanworthy quote in any public copy. The service page uses the no-quote line.
- [ ] No claim of local demand (unsourced). No invented scan stats.
- [ ] The house spec sizes are labeled as JKCA choices, not a standard.
- [ ] Pills and buttons ALL CAPS, no "!". No vendor name in any headline or pill.
- [ ] No deal copy. No testimonials.
- [ ] Our own copy has no em dashes, straight quotes, US spelling.
- [ ] §E order, matching CTA labels in hero and close, pigment drift in the hero only.
- [ ] If the demo was built, /menu-demo returns 302 and the demo code scans on two phones. If not, it isn't linked anywhere. The curl check returns 302 for every row.
- [ ] 390 / 768 / 1440 screenshots in the PR. axe clean. Tap targets 44px or more.
- [ ] Stripe in test mode only. X drafts as text, nothing posted.
