The Online Grocery List is a small, private browser tool that holds up to 100 grocery items locally so you can plan a shopping trip, check things off as you go, and copy a clean text checklist when you are ready to hand the plan over to a delivery app, a web shop, or a printed list. Nothing you enter is sent anywhere. The tool does not require an account, it does not call a remote database, and it does not bundle any analytics payload that contains your list. Every row it stores lives in a single browser profile under a versioned key only this page reads. That single design choice is also why the rest of the tool behaves the way it does: predictable inputs, an exact text export, and a clear answer to the question "where is my list, really?"

What the Browser Grocery Checklist Actually Holds
Each row in the list is a small bundle of four properties: a name you typed, one category you chose from a dropdown, a purchased flag that flips between unchecked and checked, and a browser-generated identifier the page uses internally. There is no price field, no quantity field, no barcode, no brand selector, and no separate notes field. The category choices are a fixed set of eight — Produce, Dairy, Bakery, Meat, Pantry, Frozen, Household, and Other — and Other is always available for anything that does not fit. The category is a bounded interface choice for organising rows on screen, not a nutrition classification, store taxonomy, or food-safety claim. Treat it as a sticky label that helps you scan a long list, not as advice about where a product belongs.
Because the schema is intentionally tiny, the data layer can enforce strict rules on every add. Empty names are rejected. Names longer than 80 Unicode code points after normalising whitespace are rejected. Out-of-set categories are rejected. Duplicate identifiers and duplicate names are rejected, and the saved list is never modified by a failed attempt. Pure logic tests cover all of these paths, and the page only writes the resulting valid array back to localStorage after each successful action.
The Exact Copy Format: What Hits Your Clipboard
Clicking Copy List asks your browser to write a plain-text version of the current checklist to the clipboard, and the page only reports success after the browser confirms the write. That confirmation is important — if permission is denied, the tool does not pretend the copy worked. It tells you to select the visible list manually and use your operating system's normal keyboard shortcut. The underlying write uses the standard interface documented at MDN's Clipboard.writeText reference, which is supported in current versions of every major browser.
The format itself is deliberately simple. One item per line, no numbering, no extra commentary, no automatic sort. An unchecked row begins with [ ]; a purchased row begins with [x]. After that prefix, the line holds the item name exactly as you typed it (after trim and whitespace collapse), then an em dash, with the chosen category following. A small dairy section you are about to drop into a delivery app's notes field can therefore paste in as:
[ ] Butter — Dairy [ ] Yogurt — Dairy [ ] Eggs — Other
Once you check Butter off and re-copy, the same list becomes:
[x] Butter — Dairy [ ] Yogurt — Dairy [ ] Eggs — Other
The other rows do not move, regroup, or re-sort. Checking never rewrites the name, the category, or the order. The export is a literal mirror of the rows currently held in browser storage, with two short tokens added at the front of each line.
How Items Get Added, Checked, and Cleaned Up
The full day-of-trip loop is short and maps directly onto the controls on the page:
- Open the Online Grocery List in the browser profile you intend to keep using for the whole trip.
- Type the item name into the add field and pick the closest category from the dropdown.
- Submit the row. The tool trims accidental spaces, collapses double spaces to one, and rejects the entry if the name is empty, longer than 80 code points, already on the list regardless of case, or outside the eight-category whitelist.
- Repeat until the full plan is in place. Stop at 100 items, because that is the hard ceiling.
- Mark each row purchased once it has landed in your bag or your delivery slot. Checking flips only the purchased flag.
- Use Remove to delete a single row you no longer need, or Clear Purchased to strip every checked row at once while keeping unchecked rows in their original order.
- Click Copy List when you are about to switch over to the grocery service, paste the clipboard into the search box, basket, or notes field of the order form, and place the order as usual.
The whole loop runs without creating an account, without uploading your plan, and without depending on a particular browser extension. The only persistence is the localStorage write the page makes after each successful action.
Duplicate Detection, Name Length, and the 100-Item Ceiling
Most of the tool's behaviour is governed by a small set of fixed rules rather than by clever inference, which makes the list predictable and easy to reason about. The table below summarises the rules that interact with whatever you type:
| Feature | Behaviour |
|---|---|
| Category set | Produce, Dairy, Bakery, Meat, Pantry, Frozen, Household, Other — a bounded choice of eight |
| Item name length | 1 to 80 Unicode code points after trim and whitespace collapse |
| List size limit | 100 unique items, hard cap |
| Whitespace handling | Leading and trailing spaces trimmed; multiple internal spaces reduced to one |
| Duplicate rule | Case-insensitive match on the normalised name — Milk and milk collide on purpose |
| Related-word rule | Apple and apples are different items; the tool does not infer that they refer to the same product |
| Quantity handling | None — there is no merge, no arithmetic, no unit conversion |
| Purchase toggle | Flips only the purchased flag; name and category stay exactly as added |
| Remove | Deletes the one row you selected |
| Clear purchased | Removes every checked row, keeps unchecked rows in their original order |
| Copy list export | One item per line, exact [ ] or [x] prefix, em dash, then category |
| Storage location | Browser localStorage only; never uploaded or synchronised |
Two practical consequences follow from this reference table. First, errors are explicit and visible: an empty name, an overlong name, a duplicate identifier, a duplicate name, or an out-of-set category returns a clear error message rather than silently altering the saved list. Second, because the tool does not merge quantities, infer brands, or decide that related names are identical, what you see in the exported clipboard text is exactly what you typed — only ever trimmed, single-spaced, and case-deduplicated.
LocalStorage Reality: What "Private" Actually Means
The list you build is not a cloud document and it is not a shared note. It lives in the browser profile you are using right now, under a versioned localStorage key, and the page only reads that key back when you load the tool again. That has practical consequences for how to use the checklist across trips.
- Clearing site data removes the list. If you tell your browser to clear cookies and site storage for the tool's domain, the checklist disappears with no recovery option.
- Private or incognito windows do not persist. A list built inside a private window is gone the moment that window closes.
- Switching browsers or devices does not transfer the list. A checklist on your laptop is not visible on your phone, even if both devices are signed into the same operating-system account.
- Browser cleanup tools can wipe local storage. Long-running browser profiles, security tools, and some privacy extensions rotate or purge local storage without warning.
- Browser profile access equals list access. Anyone who can open the same browser profile can read the entries you saved.
For these reasons, treat the list as a working scratchpad for a single shopping trip rather than as a long-running archive. Build it in the browser you will use to place the order, copy the result out before you close the tab, and paste it into the grocery service you ordered from. If you want a permanent record across trips, copy the checklist into a note-taking app or spreadsheet you control rather than relying on localStorage to remember it. The browser-side technical reference for how this storage behaves is documented at MDN's Window.localStorage page.
When a Browser-Saved Checklist Is the Right Tool
A 100-item, locally stored checklist is a good fit for a planning step that is small, finite, and personally useful. A weekly grocery run, a one-off restock before hosting friends, a top-up delivery for a forgotten ingredient, or a pantry sweep you want to copy into a delivery slot all fit well inside those boundaries. The checklist is also a useful scratchpad for comparing the wording a delivery service expects with the wording you actually want to use, without any of those drafts being stored anywhere except the browser profile you typed them in.
The same design does not fit other jobs. The tool does not provide dietary guidance, allergy advice, budgeting, price calculation, or stock tracking, and the category labels should not be read as nutrition information or as a store's aisle layout. It does not provide cloud backup, multi-user editing, sharing links, logins, cross-device sync, or notifications, and it explicitly warns against placing passwords, payment information, medical details, or other sensitive data in browser storage. Stick to grocery and household items, copy the result out before you close the tab if the list matters, and treat the localStorage record as exactly what it is — a private, single-device, single-trip working checklist.
If you're weighing options, How to Decide If Heart Symbol Copy Paste Is Right for You covers this in detail.