🛒 Grocy Shopping List Bridge
Send ingredients from your Obsidian recipe notes straight into your Grocy shopping list.
Works seamlessly with other recipe plugins — supports fuzzy product matching, auto-matching with thresholds, free-text items, and manual overrides.
🚀 Quick Start
- Install: Copy this plugin into
.obsidian/plugins/grocy-shoppinglist-bridge/and enable it in Obsidian. - Configure: In plugin settings, set your Grocy URL and API Key.
- Use: Open a recipe note → click the 🛒 ribbon button → ingredients appear in your Grocy shopping list.
✨ Features
- Parse
## Ingredientssections automatically (supports nested subheadings like### Sauce,#### Marinade). - Smart ingredient normalization:
1 large egg→ eggs3 cloves garlic (minced)→ garlic
- Fuzzy matching against Grocy's products with adjustable confidence.
- Multiple fallback strategies when no match is found.
- Manual overrides via inline annotations (
grocy_id,grocy:). - Ribbon button + command palette support.
- Works out-of-the-box with Recipe Grabber.
Imported recipes are parsed automatically. - Plays nicely with Recipe View.
If you use the HTML comment syntax (<!-- grocy_id: … -->), Recipe View will hide the annotation from the rendered card. - Omit notes when
grocy_idis used (configurable) -> Grocy increments cleanly by product/amount only. - Follow links(e.g. meal plan note) when the active note has no Ingredients section. Traverses linked notes up to a configurable depth.
- Skip items with
grocy_id: 0-> lets you ignore things like salt, water, or spices entirely.
📥 Installation
- Download the repo.
- Copy into your vault:
.obsidian/plugins/grocy-shoppinglist-bridge/ - Reload community plugins in Obsidian.
- Enable Grocy Shopping List Bridge.
📑 Usage
Recipe note example
## Ingredients
- 1 large egg
- 3 cloves garlic (minced)
- 1 broccoli crown
### Sauce
- 2 tbsp soy sauce
- 1 tsp sesame oil
## Directions
Mix and cook...
- Click the 🛒 ribbon button or run:
Grocy: Add ingredients to shopping list - All bullet points under Ingredients (and its subheadings) are added.
- Stops before the next top-level section (e.g.
## Directions).
⚙️ Settings
| Setting | Description |
|---|---|
| Grocy URL | Base URL of your Grocy (e.g. http://localhost/grocy or https://your-domain/grocy) |
| API Key | Create in Grocy → Settings → Manage API keys |
| Shopping List ID | Usually 1 unless you have multiple lists |
| Auto-confirm unique match | If only one candidate matches, add automatically |
| Auto-match threshold | Default 6 — top candidate score required for auto-add |
| Require score margin | Default 2 — top candidate must be this many points above runner-up |
| Debug matching | Log candidate scores & decisions to Obsidian console |
| No-match fallback | What to do when no good product is found: • Ask (chooser + free-text option) • Prompt free-text (type a note) • Free-text (auto-add note) • Skip |
| Follow links when note has no Ingredients | If enabled, will traverse linked notes and gather their Ingredients |
| Link follow depth | How many levels of links to follow (default = 1, max = 5) |
| Omit note for annotated items | If enabled, when grocy_id is present, only product_id (+amount) is sent, without the note |
🖊️ Forcing Matches (Annotations)
If you want exact control over which Grocy product is used:
By Grocy ID
- 2 tomatoes (grocy_id: 42)
Or with an HTML comment (hidden in Recipe View):
- 2 tomatoes <!-- grocy_id: 42 -->
⚠️ Recipe View will display clean ingredients without showing the
grocy_idcomment, if using the HTML notation. ⚠️ If "Omit note for annotated items" is enabled in settings, these entries will send only product + amount to Grocy (no note).
By Product Name
- 1 chili pepper (grocy: jalapeño)
This forces the matcher to look for “jalapeño” specifically.
Skipping items with grocy_id: 0
If you want to mark an ingredient so the plugin does not add it to Grocy (for example: salt, water, or spices), annotate it with:
-
Visible form:
- pinch of salt (grocy_id: 0) -
Hidden form (works with Recipe View):
- pinch of salt <!-- grocy_id: 0 -->
grocy_id: 0 tells the plugin to skip that item entirely.
🚀 Example Workflows
Fully Automated
- Auto-confirm unique = ✅
- Threshold =
6, Margin =2 - Fallback = Free-text
→ Most items auto-add. Unmatched lines go in as notes.
Semi-Automated
- Auto-confirm unique = ✅
- Fallback = Ask
→ Confident matches auto-add, ambiguous ones ask you.
Manual Control
- Auto-confirm unique = ❌
- Fallback = Ask
→ You confirm every item via chooser.
🔍 Debugging
- Enable Debug matching in settings.
- Open View → Toggle Developer Tools → Console in Obsidian.
- You'll see logs like:
Match: 1 large egg → needle: eggs top: {id:12, name:"Eggs", score:11} Auto-matched → Eggs
Changelog
-
1.0.2: Skip products with
grocy_id: 0. -
1.0.1: Follow links if
Ingredientsheadline isn't present. -
1.0.0: Initial release