Install the Recipe Widget on Any Platform
If your platform can render a script tag in the page body, it can run the widget. Here is the complete embed contract.
The Crafted Pour widget is deliberately platform-agnostic: a plain JavaScript embed with no framework dependency, no iframe, and no build step. This guide covers the general contract, plus notes for single-page apps and content security policies. If your platform has a dedicated guide (WordPress, Shopify, Squarespace, Webflow, GoDaddy), use that instead.
Before you start
- A Crafted Pour brand profile. If you have not claimed yours yet, start free at craftedpour.com/claim.
- Your products registered with Crafted Pour. Email info@craftedpour.com with your product list, product detail page URLs, a photo of each product, and UPC codes (preferred) or SKUs. We register these so your products appear as shoppable ingredients and the right recipes flow into your widget. Paid plans can manage products directly in the CMS.
- Your
plugin_id. We issue this when we provision your widget — it ties the embed to your brand's products, settings, and domain. Log in at craftedpour.com/cms — your Plugin document is listed there, and its document ID is yourplugin_id. It is also in your onboarding email, or ask info@craftedpour.com. - Your site domain on file with us. Tell us the exact domain (and any staging/preview domains) where the widget will run so we can register them. Recipes will not load from an unregistered domain.
- Brand color hex codes (6 digits, without
#) if you want the widget styled to match your site — e.g.,B42B30. A tool like htmlcolorcodes.com helps. - The ability to insert raw HTML containing
<script>tags into a page body (an “HTML embed,” “code block,” or template access).
The embed contract
Add both scripts to the body of the page where the gallery should render — SEO script first, then the widget script. The widget renders itself immediately after its own script tag:
Cocktail gallery embed (v2)
<!-- Crafted Pour SEO script (load first) -->
<script type="text/javascript"
src="https://plugin.craftedpour.com/v2/scripts/crafted-pour-recipe-plugin-seo.js">
</script>
<!-- Crafted Pour recipe widget -->
<script id="crafted-pour-recipe-plugin-script"
src="https://plugin.craftedpour.com/v2/scripts/crafted-pour-recipe-plugin.js?plugin_id=YOUR_PLUGIN_ID&catfilter=true&featured=true&primaryColor=B42B30">
</script>- Keep the
id="crafted-pour-recipe-plugin-script"on the widget script — theidform is the canonical embed. It is required on the legacy v1 script path and fully supported on v2, so it works everywhere. Never place two script tags with the sameidon one page — anidmust be unique, and duplicates mean only the first embed is processed. For multiple widgets on one page, use theclassform shown below instead. - Replace
YOUR_PLUGIN_IDwith your plugin ID. Everything after the?is configuration — the full parameter table is below. - Placement in the body determines where the gallery renders. The widget loads asynchronously and inherits your page's fonts and background, so it blends with your existing design.
Product / ecommerce pages
On a product detail page, use the product-page variant — one row of recipes plus community star ratings for that bottle, matched by UPC (preferred) or SKU:
Product page embed
<!-- Crafted Pour recipe widget — product page mode -->
<script id="crafted-pour-recipe-plugin-script"
src="https://plugin.craftedpour.com/v2/scripts/crafted-pour-recipe-plugin.js?plugin_id=YOUR_PLUGIN_ID&rows=1&ratings=true&sku=YOUR_PRODUCT_UPC_OR_SKU&primaryColor=B42B30">
</script>If your platform can inject the product's SKU/UPC into templates (Liquid, Twig, JSX, etc.), template the sku= value so one snippet covers your whole catalog. A ratings-only embed is also available: ratings=true&recipes=false.
Multiple widgets on one page
Embedding more than one widget (e.g., a ratings block up top and a recipe rail further down)? Use the class attribute instead of id so each instance is processed:
Multi-instance form
<!-- Use the class form when embedding MORE THAN ONE widget on a page -->
<script class="crafted-pour-recipe-plugin-script"
src="https://plugin.craftedpour.com/v2/scripts/crafted-pour-recipe-plugin.js?plugin_id=YOUR_PLUGIN_ID&ratings=true&recipes=false&sku=YOUR_UPC">
</script>
<script class="crafted-pour-recipe-plugin-script"
src="https://plugin.craftedpour.com/v2/scripts/crafted-pour-recipe-plugin.js?plugin_id=YOUR_PLUGIN_ID&rows=1&sku=YOUR_UPC">
</script>The class form is v2-only: it works only with the /v2/scripts/ URL shown above. The legacy v1 script (/scripts/crafted-pour-recipe-plugin.js, without /v2) finds its embed exclusively by id — a class-form tag pointed at the v1 path will not render. And never work around this by duplicating the id: only the first tag with a given id is processed.
Single-page apps (React, Next.js, Vue, and friends)
- The widget script processes embeds when it loads. In an SPA, inject the script tag after the target route/component has mounted (e.g., appending the script element in a
useEffect), so the script tag exists in the DOM when the loader runs. - The loader guards against double-initialization, but if you client-side-navigate away and back, re-inject a fresh script element rather than reusing the old one.
- For server-rendered frameworks, render the script tags into the page HTML — the SEO script is classic (non-module) and safe to server-render.
Content-Security-Policy
If your site sends a CSP header, allow our origin:
CSP additions
script-src … https://plugin.craftedpour.com;
connect-src … https://plugin.craftedpour.com https://*.googleapis.com;
img-src … https://plugin.craftedpour.com https://*.googleusercontent.com https://firebasestorage.googleapis.com data:;Locked-down CSP and want the exact directive list for your setup? Email support@craftedpour.com — we will confirm against your policy.
Customize the widget: full parameter reference
Everything after the ? in the script URL configures your widget. Chain parameters with &. All are optional except plugin_id.
| Parameter | Example | What it does |
|---|---|---|
plugin_id | plugin_id=qYyFJ6… | Required. Your widget ID from Crafted Pour — loads your products, recipes, and partner settings. |
rows | rows=2 | Show a fixed number of rows with paging arrows. Omit for an infinite-scroll gallery. Use rows=1 on product pages. |
featured | featured=true | Adds the curated FEATURED rail at the top — hand-picked seasonal recipes photographed with your bottle. Toggle its content via the CMS (show_featured). |
ratings | ratings=true | Shows the product-ratings widget (community tasting notes and star ratings) above the recipes. Designed for single-product pages. |
recipes | recipes=false | Set to false to hide the recipe grid — combine with ratings=true for a ratings-only embed. |
catfilter | catfilter=true | Adds a category (spirit-type) filter dropdown. |
productfilter | productfilter=true | Lets visitors filter recipes by your products. Rendered as a dropdown or as visual product pills depending on your partner-level filter style setting. |
brandfilter | brandfilter=true | Brand selector — for portfolios, groups, and retailers managing multiple brands in one widget. |
product | product=KN3ARO… | Restrict the widget to one product by its Crafted Pour product ID. Only needed when you cannot use sku. |
sku | sku=012345678905 | Match a product by UPC (preferred) or SKU — ideal on ecommerce product templates where the platform injects the value dynamically. Repeatable for multi-SKU pages. |
primaryColor | primaryColor=B42B30 | Main accent color (buttons, highlights). Hex without #. |
color | color=B42B30 | Supported alias for primaryColor — many existing installs use it and it keeps working. If both are present, primaryColor wins. Prefer primaryColor for new installs. |
secondaryColor | secondaryColor=FFFFFF | Background for tags and ingredient boxes. |
backgroundColor | backgroundColor=FFFFFF | Widget background. Defaults to transparent so it inherits your page background. |
textColor | textColor=000000 | Main text color. |
textPosition | textPosition=bottom | Moves recipe name and creator below each photo instead of overlaid on it — a cleaner look on minimal sites. |
recipeItemBorder | recipeItemBorder=0 | Set to 0 for square recipe-card corners (matches squared-off site designs). Omit for the default rounded cards. |
Partner-level behavior — editor's notes, smart product placement (competitor masking), generic-recipe inclusion, and filter style — is configured per brand rather than per embed. See the Partner Settings guide and manage them at craftedpour.com/cms.
Recipe detail pages & SEO setup
Every recipe card links to a full recipe page on your domain (your gallery URL with ?cp_rid=<recipe> appended). The SEO script in the embed above is what makes those pages count for search:
- Server-rendered recipe content. Title, ingredients, instructions, and your brand's AI-sommelier editor's note are served before any JavaScript runs, so Google indexes real content on your URL — not an empty shell.
- Structured data. Machine-readable Recipe markup including star ratings, making your pages eligible for Google's rich results and readable by AI assistants like ChatGPT and Gemini.
- Canonical and social tags. Correct canonical, Open Graph, and Twitter URLs are set per recipe automatically.
That is why the two-script embed matters: keep the SEO script before the widget script, on the same page.
Submit your recipe sitemap to Google
- We auto-generate a sitemap of every recipe URL on your domain at:
https://plugin.craftedpour.com/sitemaps/YOURDOMAIN.com_recipes.xml - Create a redirect on your domain — e.g.
yourdomain.com/recipe-sitemap.xml→ the URL above. - In Google Search Console, verify your domain and submit the redirect URL under Sitemaps.
How to know it worked
- The gallery renders. Open the published page — you should see a grid of recipe cards with photos and a “Powered by Crafted Pour” badge. If you enabled
featured=true, a FEATURED rail leads the page. - Cards open recipe pages on your domain. Click any recipe — the URL should stay on your site and gain
?cp_rid=…, showing the full recipe with your product linked in the ingredients. - Your products are shoppable. On a recipe that uses your product, the ingredient should link out with your “shop” call-to-action (competitor names masked if smart product placement is on).
- SEO content is being served. On a recipe page (with
cp_ridin the URL), use View Source and search forrecipe-seo-contentor the recipe name — it should appear in the raw HTML. - No console errors. Open your browser's developer tools (F12) → Console. A healthy install logs
Recipe widget loadedwith no red errors.
Troubleshooting
- Your platform strips script tags from page content. Look for an “HTML embed,” “custom code,” or “code injection” feature — most builders restrict scripts in rich-text fields but allow them in a dedicated code element. If there is truly no way to add a script, ask us about the white-glove options below.
- The script shows as plain text on the page. It was pasted into a rich-text/paragraph field instead of an HTML/code element. Re-paste it into your platform's HTML embed field.
- Nothing renders at all. Check that the script URL is exactly
https://plugin.craftedpour.com/v2/scripts/crafted-pour-recipe-plugin.jsand that your page editor did not strip the<script>tag (some platforms restrict scripts on lower-tier plans). - An empty grid loads. Usually a wrong or missing
plugin_id, or your domain is not yet registered with us. Email support@craftedpour.com with your page URL. - Testing on a staging or preview domain. Send us the full preview URL first so we can whitelist it — unregistered domains will not load recipes.
- Old content keeps showing after changes. Clear your site/CDN cache and hard-refresh (Cmd/Ctrl + Shift + R).
- Colors look wrong. Color values must be 6-digit hex without the
#—primaryColor=B42B30, notprimaryColor=#B42B30. A#starts the URL fragment, so everything from it onward is silently dropped and your color never reaches the widget. The same applies to the legacycolor=parameter. - Your site uses a Content-Security-Policy. Allow
plugin.craftedpour.cominscript-src,connect-src, andimg-src.
Want the deep-dive on what the widget does for your brand — smart product placement, brand-aware photos, AI editor's notes, star ratings in Google? See the full feature tour.
Install it free — or let us do it for you
Everything on this page is free to self-install with your existing widget. Prefer white-glove? We offer paid installation — custom styling, placement, and theme work included — so it is live on your site without you touching a line of code.