🧩 Chrome Extension Recipe Capture
Audience: User, Developer, Support Related: Overview · Importing And Discovery · Social Import · Recipe Import
Capture Page collects available structured recipe data, page metadata, visible content, and supported social evidence, then lets the user review or complete the recipe before submission. Quick Add submits the current URL for server-side extraction.
The extension must show source provenance, avoid capturing unrelated page data, use authenticated Blackcap APIs, and handle partial social evidence without inventing missing recipe content.
This pass moves the extension closer to Chrome Web Store readiness while preserving local/self-hosted use.
What changed
- Manifest V3 remains in place.
- Broad static host permissions were replaced with optional host permissions.
- Added an options page for configuring the Blackcap Pi URL and token.
- Added a first-run connection card in the popup.
- Moved token storage from
chrome.storage.synctochrome.storage.local. - Added a one-time migration from the original
adminTokensync value to the new localapiTokenvalue. - Added connection testing against
/api/recipes/ping. - Added support for a dedicated
[security] extension_api_token. - Kept
X-Blackcap-Tokencompatibility while addingAuthorization: Bearer <token>. - Added cache status polling after a queued recipe cache build.
- Tightened recipe API CORS handling so it no longer defaults to
*.
Recommended configuration
[security]
require_auth = true
admin_token =
extension_api_token =
extension_allowed_origins =
allow_lan_without_auth = false
enforce_https_external = true
rate_limit_enabled = true
login_attempts_per_minute = 8
api_attempts_per_minute = 60
If require_auth = true and either token is blank, the Admin service will generate the missing token on startup and save it back to the config file.
Use:
admin_tokenfor browser login and full Admin UI accessextension_api_tokenfor the Chrome extension and recipe API clients
Add Recipe capture flow
The Add Recipe popup presents Capture Page as the primary path and Quick Add as the secondary path. Capture Page should be visually primary because it works best for the current browser tab, including logged-in recipe pages that the Blackcap server cannot fetch directly. Quick Add still sends a URL to Blackcap for server-side import.
Capture Page opens a larger review/edit state before saving. Users can correct the shared recipe name, captured description, source URL, image URL, recipe type/layout, time and serving metadata, nutrition text, ingredients, and instructions. The extension extraction order is JSON-LD Recipe data, microdata Recipe data, common recipe-card/plugin selectors, then bounded visible DOM fallback with review warnings when confidence is low.
Quick Add and Capture Page intentionally share one editable recipe name field. Capture Page does not keep a separate capture-only title/name field. When the Capture Page review is expanded, the Quick Add description is hidden so the popup does not show two competing descriptions; the Capture Page description remains editable and is used for the captured recipe. If the shared name is blank, capture extraction may populate it from the page title. If the captured description is blank, save can fall back to the Quick Add description rather than sending an empty description.
The extension does not permanently convert recipe units. It sends captured/source text to Blackcap. Organization Preferred Recipe Units are applied by backend render/display/shopping services so the original source text remains intact.
Developer install test
- Restart the Admin service so the config defaults/tokens are created.
- Open
inky_menu_config.iniand copy[security] extension_api_token. - Open
chrome://extensions/. - Enable Developer Mode.
- Click Load unpacked.
- Select
Blackcap-Pi/Blackcap-Pi-Extension. - Open the extension popup or options page.
- Enter the Blackcap Pi base URL and extension token.
- Click Test & Save Connection.
- Open a recipe page and click Send Recipe.
Shop With assisted shopping
The extension also supports Shop With assisted shopping when opened on a configured shopping provider site. Provider availability comes from the organization associated with the selected extension token. The side panel can detect known provider hosts, offer active Blackcap shopping lists, and step through the consolidated items in the selected list.
Important behavior:
- provider/store selection is stored in the active shopping session, so changing the store mid-session does not snap back to the provider default;
- providers can expose a closed set of store modes or a free-form store field with suggestions;
- Shipt uses free-form store text and can fall back to
storesthrough the provider default store setting; - Amazon is labeled Amazon and exposes Whole Foods Market, Amazon Fresh, Amazon.com, and Amazon Grocery store modes;
- Got It and Already Have It update every backing row for a consolidated assisted item;
- Review shows the purchased/checked items from the session and supports Reshop by clearing the backing rows;
- Complete finishes the shopping session and closes the side panel without navigating to Blackcap;
- Return is the only extension action that should bring the user back to Blackcap.
External Shopping List browser bridge
The extension also powers the attended Household/External Shopping List bridge for organization connections such as Google Keep and Amazon/Alexa. This is separate from normal Shop With retailer shopping.
Important behavior:
- External Shopping List sync/update requires desktop Chrome with the Blackcap extension installed and connected to the same Blackcap organization.
- Provider pages open in popup-sized windows so the user can see sign-in, MFA, site-access, and selector issues.
- The side panel opens for both import sync and provider check-off, showing item counts, item names when available, successes, and failures.
- Google/Amazon passwords are not stored by Blackcap; the extension uses the user's already signed-in browser session.
- Mobile Shop a List can include the last-synced Household List snapshot but cannot run provider browser automation or check off external provider items.
- For normal shopping lists, provider check-off runs when the Admin list is completed or the Shop With session is finished, not when each item checkbox is toggled.
- For shopping the Household List directly, provider check-off is triggered by Update External List in the Admin shopping view.
- Failed provider check-offs are recorded and the affected item is put back on the Household List.
Troubleshooting points:
- If the side panel asks for site access, approve the Chrome host-permission prompt for the provider page.
- If the provider page is signed out, complete sign-in/MFA in the popup, then continue the sync/update flow.
- If Google Keep captures the wrong list, open the target Keep note and confirm the URL includes
#LIST/...before saving the connection. - If Amazon imports unrelated cart/header data, verify the connection uses the Alexa Shopping List URL and tune the Amazon extractor if Amazon changed the page markup.
See Household and External Shopping Lists for the admin/user workflow.
Chrome Web Store preparation still needed
- Confirm the extension-list icon set uses
icons/extension-list-icon16.png,icons/extension-list-icon32.png,icons/extension-list-icon48.png, andicons/extension-list-icon128.png. - Prepare store promotional graphics.
- Write a short privacy policy explaining that recipe page URLs and entered metadata are sent only to the user's configured Blackcap Pi server.
- Prepare screenshots of setup and send flows.
- Decide on the final public extension name.
- After publishing, optionally add the published
chrome-extension://<extension-id>value to[security] extension_allowed_origins.
Future pairing idea
A QR pairing flow can be added later by having the Admin UI generate a short-lived pairing code that returns the extension API token. The manual URL + token flow should remain as the reliable fallback.
Field-specific Blackcap emoji controls
The extension Add Recipe facade now places a small 🙂 button beside each eligible recipe text field rather than exposing one ambiguous page-level control. The button targets only its associated name, description, or manual-notes field, inserts at the cursor or replaces selected text, restores focus, and dispatches normal input/change events.
The extension continues to load the existing Blackcap-supported emoji list from the configured Blackcap server. The implementation remains in popup.js and does not use unsafe inline JavaScript, preserving Manifest V3 content-security requirements.
Recipe Type and post-import sharing
All Extension flows that create a recipe use Blackcap's server-provided canonical Recipe Type list. Recipe Type is requested early, before the user chooses Quick Add, Capture Page, or—for social recipes—whether to use AI review. That early selection is carried through captured-page review, deterministic social extraction, optional AI review, and the final recipe payload. A valid deterministic/AI type may update the preselection when appropriate, but the user can override it before creation. Older Extension clients that omit Recipe Type continue to receive the server default.
After a recipe is created, editable content is committed, and the normal recipe cache reports ready, the completion state offers Share and Close. Share is withheld when the cache is pending/failed or when the current token user lacks the existing recipe-sharing permission. Once Share is pressed, the initial Share/Close/readiness area is hidden; the expanded PDF-sharing form becomes the active action area and provides Send PDF and Close together so there are not two competing Close actions.
The first Extension sharing method is PDF, and it intentionally reuses the existing Admin Email PDF behavior. Blackcap renders the share-friendly PDF, emails it to the entered recipient(s), and removes the temporary share PDF afterward. This is distinct from Share via Link, whose tokenized URL is a Blackcap-to-Blackcap recipe-import link rather than a public PDF URL. The Extension does not mislabel that import link as PDF sharing or create a second recipe-sharing backend.
Browser regression source selection
The optional browser regression exercises recipe capture through the actual Chromium page, Extension popup/review, and Blackcap API path; it does not create the recipe directly through a regression API shortcut. When Regression configuration contains a valid safe public recipe URL, that exact URL is used. If the setting is empty, malformed, unsafe, a placeholder/test hostname, unsupported by safe public URL validation, or otherwise rejected during selection, the run-specific Blackcap recipe fixture is used instead. A valid configured URL is attempted exactly as supplied; if browser navigation itself is unavailable, the scenario records an external warning and completes its deterministic gate with the active fixture. Once the public page loads, capture/content failures remain real failures rather than being hidden by fallback. Diagnostics state whether the source was the configured public recipe or deterministic fixture without persisting URL credentials or secrets.
The same browser group now exercises social recipe import at two depths using Blackcap-owned active-run fixtures. The deterministic fixture must travel from Capture Page through final recipe/cache creation with zero AI jobs and zero AI Seeds. The AI fixture must naturally reach the Extension's AI-review controls, select the cheapest enabled usable/affordable Social Recipe Extraction profile from the exact profile elements rendered by the Extension, confirm the charge, capture bounded fixture media, wait for the real reviewed draft, and import/cache it. Browser startup verifies that both the Blackcap Admin session and Extension token resolve to Regression Org A / Org A Admin before these flows run. Fixture URLs are inspectable from the active Run Details 🪑 Fixtures dialog and disappear with active-run fixture authorization.