To integrate Ecwid (now Lightspeed E-Series) with Bolt.new, either embed Ecwid's storefront JavaScript snippet directly into a React component for an instant working store, or use the Ecwid REST API with your store ID and secret key to build custom product pages and cart flows. The embed approach works immediately in Bolt's preview. The REST API approach keeps credentials server-side in Next.js API routes.
Two Ways to Add a Working E-Commerce Store with Ecwid in Bolt.new
Ecwid's core design principle is embeddability — it was built from day one to drop into any existing website without replacing it. You add two lines of HTML: a div with an id that Ecwid targets, and a script tag that loads the storefront. Ecwid's JavaScript reads your store ID from the script URL, fetches your products, and renders a complete shopping experience with product grid, product pages, cart, and checkout — all inside that div. In Bolt.new, you translate this to a React component that injects the script tag via useEffect and renders the target div.
The embed approach requires zero API credentials and works immediately in Bolt's WebContainer preview. Customers who click through to checkout complete their purchase on Ecwid's hosted checkout (or Ecwid's custom domain if you've configured one). Your products, inventory, and orders are all managed in the Ecwid merchant dashboard. This is the lowest-effort path to a working online store.
For builders who want more control — custom product page designs, branded checkout, or integration with other parts of their app — Ecwid's REST API provides access to the same data. The API requires an access token (your store's secret key from Dashboard → Apps → Legacy API keys) and uses simple HTTP Bearer authentication. Products, categories, orders, customers, and inventory are all accessible. API calls run through Next.js API routes to protect your token. The REST API is the right choice when you want to design your own product pages while still using Ecwid as the backend for inventory and order management.
Integration method
Ecwid offers two integration paths for Bolt.new: the JavaScript embed snippet (a script tag that renders Ecwid's full storefront directly in a React component using useEffect) works immediately without any API credentials, and the Ecwid REST API (using your store ID and secret token in Next.js API routes) enables custom product displays, custom cart UIs, and order management. Both approaches avoid TCP sockets and use HTTPS — fully compatible with Bolt's WebContainer.
Prerequisites
- An Ecwid account at ecwid.com — free plan available with up to 5 products
- Your Ecwid Store ID (visible in Dashboard → Settings → General, or in the embed code URL)
- Your Ecwid Secret Key from Dashboard → Apps → Legacy API keys (needed only for REST API approach)
- A Bolt.new project — Next.js recommended for the REST API approach, Vite works for the embed-only approach
- Products added to your Ecwid store before testing (at least 2-3 to verify catalog display)
Step-by-step guide
Get Your Ecwid Store ID and API Credentials
Get Your Ecwid Store ID and API Credentials
Log in to your Ecwid account at ecwid.com and open your merchant dashboard. Your Store ID is the most important identifier — it is a numeric string visible in the browser URL bar when you're in the dashboard (e.g., app.ecwid.com/cp/#/overview/12345678, where 12345678 is your store ID) and in your embed code. For the REST API, you need a secret key. Go to your Ecwid dashboard → Apps (left sidebar) → All Applications → scroll down to 'Legacy API keys' or find it under the developer section. Click 'Legacy API keys' to see your store's public and secret keys. The secret key is used for server-side API calls; the public key is not needed for most operations. Note your Store ID and Secret Key. Add them to your .env file: NEXT_PUBLIC_ECWID_STORE_ID (safe to expose client-side — it's in the public embed script URL anyway) and ECWID_SECRET_KEY (server-side only — grants full read/write access to your store's orders, customers, and products). Ecwid's API base URL follows this pattern: https://app.ecwid.com/api/v3/{storeId}/. All API calls append your store ID to this base URL and require a Bearer token with your Secret Key in the Authorization header. The REST API uses HTTPS exclusively — compatible with Bolt's WebContainer.
Set up the project for Ecwid integration. Create a .env.local file with NEXT_PUBLIC_ECWID_STORE_ID=your_store_id_here and ECWID_SECRET_KEY=your_secret_key_here. Create a src/lib/ecwid.ts helper that exports an ecwidFetch(path, options?) function calling https://app.ecwid.com/api/v3/${process.env.NEXT_PUBLIC_ECWID_STORE_ID}/{path} with Authorization: Bearer ${process.env.ECWID_SECRET_KEY} header. Return parsed JSON. Use TypeScript.
Paste this in Bolt.new chat
1// src/lib/ecwid.ts2const STORE_ID = process.env.NEXT_PUBLIC_ECWID_STORE_ID;3const BASE_URL = `https://app.ecwid.com/api/v3/${STORE_ID}`;45export async function ecwidFetch<T>(6 path: string,7 options: RequestInit = {}8): Promise<T> {9 const secretKey = process.env.ECWID_SECRET_KEY;10 if (!secretKey) throw new Error('ECWID_SECRET_KEY is not set');1112 const response = await fetch(`${BASE_URL}/${path}`, {13 ...options,14 headers: {15 Authorization: `Bearer ${secretKey}`,16 'Content-Type': 'application/json',17 ...options.headers,18 },19 });2021 if (!response.ok) {22 throw new Error(`Ecwid API error ${response.status}: ${await response.text()}`);23 }2425 return response.json();26}2728export const ECWID_STORE_ID = STORE_ID;Pro tip: NEXT_PUBLIC_ECWID_STORE_ID is safe to expose in client-side code because it is already public in the embed script URL. ECWID_SECRET_KEY must never be in client code — it grants write access to your store including creating and modifying orders.
Expected result: Your .env file has both the store ID and secret key. The ecwidFetch helper is available for all API routes. NEXT_PUBLIC_ECWID_STORE_ID is accessible in both client and server code.
Embed the Ecwid Storefront Widget (Easiest Path)
Embed the Ecwid Storefront Widget (Easiest Path)
The embed approach adds a fully working store to your Bolt.new app with minimal code. Ecwid's script tag loads their storefront JavaScript, which mounts a complete shopping experience inside the target div. In React, you cannot add script tags directly to JSX — use useEffect to inject the script programmatically after the component mounts. The embed code consists of two elements: a script tag that loads Ecwid's storefront script from app.ecwid.com/script.js with your store ID as a query parameter, and a div with id='my-store-{storeId}' that Ecwid targets for rendering. The script tag must be added to the DOM (not the Next.js script component) and must load after the target div exists in the DOM. Customize the storefront appearance using the window.ec.config object, which you can set before the script loads. Options include defaultCategoryId (which category to show first), scrollToCurrentPage (prevent page scrolls), and view (list or grid). CSS customization is limited to overriding Ecwid's class names — the widget renders its own HTML with stable class names that you can target. The Ecwid widget works in Bolt's WebContainer preview immediately after you add the code — no deployment needed to see the live store. Customers can browse products and add to cart in the preview. Checkout will redirect to Ecwid's hosted payment page.
Create a Shop page at app/shop/page.tsx with an EcwidStore component. The component should: render a div with id='ecwid-store', use useEffect to create and append a script element with src='https://app.ecwid.com/script.js?${process.env.NEXT_PUBLIC_ECWID_STORE_ID}&data_platform=code' and defer=true to document.body, and clean up by removing the script and clearing window.ecwid_onBodyDone on unmount. Add window.ec = window.ec || {}; window.ec.config = { baseUrl: '/', storefrontUrls: { cleanUrls: true } }; before the script tag. Style the container with min-height: 600px.
Paste this in Bolt.new chat
1// app/shop/page.tsx2'use client';3import { useEffect } from 'react';45export default function ShopPage() {6 const storeId = process.env.NEXT_PUBLIC_ECWID_STORE_ID;78 useEffect(() => {9 if (!storeId) return;1011 // Configure Ecwid before loading script12 (window as any).ec = (window as any).ec || {};13 (window as any).ec.config = {14 baseUrl: '/shop',15 storefrontUrls: { cleanUrls: true },16 };1718 const script = document.createElement('script');19 script.src = `https://app.ecwid.com/script.js?${storeId}&data_platform=code`;20 script.defer = true;21 script.id = 'ecwid-script';22 document.body.appendChild(script);2324 return () => {25 // Clean up on unmount26 const existingScript = document.getElementById('ecwid-script');27 if (existingScript) document.body.removeChild(existingScript);28 delete (window as any).ecwid_onBodyDone;29 };30 }, [storeId]);3132 return (33 <div className="max-w-6xl mx-auto px-4 py-8">34 <h1 className="text-3xl font-bold mb-8">Our Store</h1>35 <div id={`my-store-${storeId}`} className="min-h-96" />36 </div>37 );38}Pro tip: Ecwid's embed script conflicts if loaded more than once. Use a script ID check (document.getElementById('ecwid-script')) before appending, and always remove the script on component unmount to prevent duplicate store instances when navigating away and back.
Expected result: The /shop page renders your full Ecwid storefront embedded in your Bolt.new app. Products load from your Ecwid account, customers can add items to cart, and the store appearance is controlled by your Ecwid theme settings. This works immediately in the Bolt preview.
Build a Custom Product Grid with the REST API
Build a Custom Product Grid with the REST API
For more design control, use Ecwid's REST API to fetch product data and render products using your own React components. This approach lets you design the product grid, product cards, and filtering UI exactly as you want, while Ecwid handles inventory, pricing, and checkout. The Ecwid products endpoint is /products and returns a paginated list of products with id, name, price, description, thumbnailUrl, imageUrl, quantity (inventory), and url (the direct Ecwid product page URL for checkout). Filter by category with ?category={id}, search with ?keyword={term}, and paginate with ?limit=20&offset=0. For checkout, you have two options: link to Ecwid's product page URL (simplest — uses Ecwid's full checkout) or use the Ecwid JS API (window.Ecwid.openPage()) to open specific products in the embedded widget. For a custom storefront with Ecwid as the backend, linking to Ecwid's product URL is the most reliable checkout path. Cache product data in your app — Ecwid's free plan has API rate limits (API calls are limited, though the specific numbers are not publicly documented). Fetching on every page load is inefficient; cache for 5-15 minutes using Next.js's built-in fetch cache or a simple in-memory map.
Create /api/ecwid/products/route.ts that accepts optional query params: category (category ID), limit (default 20), offset (default 0), keyword (search). Fetch from Ecwid API using the ecwidFetch helper and return a cleaned list: id, name, price, originalPrice (if discounted), thumbnail, inStock, url, and shortDescription (first 100 chars of description). Also create /api/ecwid/categories/route.ts that returns the store's categories list with id, name, and productCount. Add 5-minute caching using Next.js fetch options.
Paste this in Bolt.new chat
1// app/api/ecwid/products/route.ts2import { NextRequest, NextResponse } from 'next/server';3import { ecwidFetch } from '@/lib/ecwid';45interface EcwidProduct {6 id: number;7 name: string;8 price: number;9 compareToPrice?: number;10 thumbnailUrl: string;11 quantity: number;12 unlimited: boolean;13 url: string;14 shortDescription: string;15 enabled: boolean;16}1718interface EcwidProductsResponse {19 items: EcwidProduct[];20 total: number;21 count: number;22 offset: number;23 limit: number;24}2526export async function GET(request: NextRequest) {27 const params = request.nextUrl.searchParams;28 const query = new URLSearchParams({29 limit: params.get('limit') ?? '20',30 offset: params.get('offset') ?? '0',31 enabled: 'true',32 ...(params.get('category') && { category: params.get('category')! }),33 ...(params.get('keyword') && { keyword: params.get('keyword')! }),34 });3536 try {37 const data = await ecwidFetch<EcwidProductsResponse>(38 `products?${query}`,39 { next: { revalidate: 300 } } as any // 5 minute cache40 );4142 const products = data.items43 .filter(p => p.enabled)44 .map(p => ({45 id: p.id,46 name: p.name,47 price: p.price,48 compareToPrice: p.compareToPrice ?? null,49 thumbnail: p.thumbnailUrl,50 inStock: p.unlimited || p.quantity > 0,51 url: p.url,52 description: p.shortDescription?.slice(0, 100) ?? '',53 }));5455 return NextResponse.json({ products, total: data.total });56 } catch (err: any) {57 return NextResponse.json({ error: err.message }, { status: 500 });58 }59}Pro tip: Ecwid product URLs (p.url) link directly to the product page on Ecwid's hosted storefront or your custom domain. Use these URLs as the 'Buy Now' button target — clicking them takes the customer to Ecwid's checkout without you needing to build payment processing.
Expected result: The /api/ecwid/products endpoint returns your Ecwid store's products in a clean format. The /api/ecwid/categories endpoint returns your categories for filtering. Your custom product grid displays real product data from your Ecwid store.
Customize the Embed and Deploy
Customize the Embed and Deploy
Customize the Ecwid embed appearance and behavior before deploying. Ecwid's JavaScript API exposes configuration options via window.ec.config before the script loads, and event hooks via window.Ecwid.OnAPILoaded for post-load customization. For CSS customization, Ecwid's widget elements have stable class names prefixed with ec- that you can override in your global CSS. Common customizations include matching the store font to your app's typography, adjusting button colors to match your brand, and hiding Ecwid's default breadcrumbs if you have your own navigation. Keep CSS overrides minimal — Ecwid updates their widget CSS periodically and overrides can break. For the Ecwid widget specifically, no webhook setup is required for read-only storefront functionality. You do not need a deployed URL to test product browsing and add-to-cart in the Bolt preview. However, if you want to receive order notifications in your app (via Ecwid webhooks that POST to your server when orders are placed), you will need a deployed URL — Bolt's WebContainer cannot receive incoming HTTP connections. Configure order webhooks in your Ecwid dashboard under Settings → Notifications → Webhooks after deploying. To deploy: publish to Netlify or Bolt Cloud, set NEXT_PUBLIC_ECWID_STORE_ID and ECWID_SECRET_KEY as environment variables in your hosting dashboard, and trigger a new deployment. The Ecwid widget loads from Ecwid's CDN and requires no Ecwid-specific deployment configuration.
Add CSS customization for the Ecwid store widget in app/globals.css. Override the .ec-storefront font to match the app font. Change the primary button color in .ec-cart__checkout-button to the app's blue color (#2563eb). Hide the Ecwid footer branding (.ec-footer). Add responsive styles so the product grid stacks to 1 column on mobile. Create a simple store header with the store name and a shopping cart icon that shows the item count using Ecwid's window.Ecwid.Cart.get() API.
Paste this in Bolt.new chat
1/* app/globals.css — Ecwid widget customization */23/* Match app typography */4.ecwid,5.ec-storefront {6 font-family: inherit !important;7}89/* Brand primary button color */10.ec-cart__checkout-button,11.ec-storefront .form-control__button--primary {12 background-color: #2563eb !important;13 border-color: #2563eb !important;14}1516.ec-cart__checkout-button:hover,17.ec-storefront .form-control__button--primary:hover {18 background-color: #1d4ed8 !important;19}2021/* Hide Ecwid footer on free plan */22.ec-footer {23 display: none !important;24}2526/* Responsive grid on mobile */27@media (max-width: 640px) {28 .grid-list .grid-list__list-inner {29 grid-template-columns: 1fr !important;30 }31}Pro tip: Ecwid's widget loads asynchronously after the page renders. If you need to react to cart events (item added, checkout started), use window.Ecwid.OnAPILoaded.add() to register event handlers after the Ecwid JS API is ready. Do not try to call window.Ecwid methods synchronously in useEffect — the API may not be loaded yet.
Expected result: The Ecwid storefront matches your app's visual style with custom button colors, matching typography, and responsive mobile layout. The app deploys to Netlify or Bolt Cloud with correct environment variables, and the embedded store works on the deployed site.
Common use cases
Instant Embedded Store with Ecwid Widget
Add a fully functional online store to your Bolt.new app in minutes by embedding the Ecwid storefront widget. Customers browse products, add to cart, and check out entirely within Ecwid's embedded interface. No custom API integration needed.
Add an Ecwid store to my app. Create a Shop page at /shop with an EcwidStore React component. In the component, use useEffect to inject two elements: a div with id='my-store-123' and a script tag that loads https://app.ecwid.com/script.js?12345678&data_platform=code (replace 12345678 with my store ID stored in NEXT_PUBLIC_ECWID_STORE_ID). Style the store container to take the full page width. Add navigation links from the header to /shop. Make it look clean with a white background.
Copy this prompt to try it in Bolt.new
Custom Product Grid with Ecwid as Backend
Build a fully custom product display using your own React components and Tailwind CSS, powered by Ecwid's product data from their REST API. Customers see your custom-designed product pages, then click through to Ecwid's checkout for payment processing.
Build a custom product catalog using the Ecwid REST API. Create /api/ecwid/products/route.ts that fetches products from https://app.ecwid.com/api/v3/{storeId}/products using the secret key from ECWID_SECRET_KEY env var. Return products with name, price, description, thumbnailUrl, inStock, and url (Ecwid product page URL). Build a product grid page with custom card design, filter by category dropdown, and a 'Buy Now' button that links to the Ecwid product page for checkout. Cache products for 5 minutes.
Copy this prompt to try it in Bolt.new
Store Analytics Dashboard
Build an internal dashboard that displays your Ecwid store metrics: recent orders, revenue totals, bestselling products, and inventory levels. The Ecwid REST API exposes all order and product data needed for a management view.
Create an admin dashboard at /admin/store that shows Ecwid store analytics. Use the Ecwid REST API to fetch: recent orders (last 10, with customer name, total, status), today's revenue total (sum of completed orders from today), top 5 products by quantity sold in the last 30 days, and products with low stock (quantity < 5). Display as metric cards and data tables. Add a manual Refresh button. Protect the page with a simple password check using a PASSWORD env variable.
Copy this prompt to try it in Bolt.new
Troubleshooting
Ecwid store shows 'Your store ID is incorrect' or displays a blank page after the embed
Cause: The NEXT_PUBLIC_ECWID_STORE_ID environment variable is missing, contains extra whitespace, or the store ID in the script URL does not match an active Ecwid store.
Solution: Verify the store ID by logging in to your Ecwid dashboard and checking the URL in the browser — the number in the URL path is your store ID. Ensure NEXT_PUBLIC_ECWID_STORE_ID in your .env matches this number exactly with no spaces. Also confirm the div id matches the format 'my-store-{storeId}'.
1// The div ID must exactly match 'my-store-' + your store ID2// If your store ID is 12345678:3<div id="my-store-12345678" className="min-h-96" />4// And the script src must include the same store ID:5script.src = `https://app.ecwid.com/script.js?12345678&data_platform=code`;Ecwid store widget loads but products don't appear, showing empty category pages
Cause: You have no products added to your Ecwid store, products are set to 'Disabled' status, or the products are in a category that is not set as the default display category.
Solution: Log in to your Ecwid dashboard and verify that: products exist and are set to 'Enabled' status, they are visible in at least one category, and the category is not set to 'Hidden'. For a test store, add 2-3 simple products with names and prices to verify the embed is working correctly.
Ecwid REST API returns 401 Unauthorized when calling from Next.js API routes
Cause: The ECWID_SECRET_KEY environment variable is not set or is incorrect. Note that Ecwid distinguishes between Public Token (for read-only public data) and Secret Token (for full access including orders). Using the Public Token for order-related endpoints returns 401.
Solution: In the Ecwid dashboard under Apps → Legacy API keys, copy the Secret Token (not the Public Token). The secret token typically starts with 'secret_'. Update ECWID_SECRET_KEY in your .env file with this value. Redeploy after updating environment variables in production.
Best practices
- Use NEXT_PUBLIC_ECWID_STORE_ID for the embed script (client-safe) but never expose ECWID_SECRET_KEY in client-side code — the secret key gives write access to orders and customer data.
- Clean up the Ecwid script on React component unmount to prevent duplicate store instances and memory leaks when users navigate between the shop page and other pages.
- Cache REST API responses for 5-15 minutes — Ecwid's catalog changes infrequently, caching reduces API calls and speeds up product page loads.
- For the embed approach, set window.ec.config before loading the Ecwid script to configure the storefront behavior — post-load configuration via the Ecwid JS API is also possible but more complex.
- Test the checkout flow on your deployed site (not just the Bolt preview) to confirm that redirect and post-purchase behavior works correctly with your custom domain configuration.
- Use Ecwid's built-in mobile-responsive design rather than fighting it with aggressive CSS overrides — Ecwid's widget is well-optimized for mobile and overrides can cause layout issues.
- Set up Ecwid's SEO settings (meta titles, descriptions, URLs) in the Ecwid dashboard to ensure product pages are indexed correctly if you're using the embed widget for your main storefront.
Alternatives
WooCommerce is a full WordPress-based e-commerce platform with deeper customization than Ecwid, but requires a WordPress site — Ecwid is designed to embed into any website including Bolt.new apps.
BigCommerce is a more feature-rich e-commerce platform with headless commerce APIs, appropriate for larger catalogs, while Ecwid is simpler to embed for small to medium stores.
Magento (Adobe Commerce) is enterprise-grade with extensive customization but requires significant server infrastructure, whereas Ecwid is a hosted solution with a simple embed path.
Shift4Shop is a full-hosted e-commerce platform with a free tier, more comparable to Shopify than to Ecwid's lightweight embeddable model.
Frequently asked questions
Can I use Ecwid in Bolt.new during development without deploying first?
Yes — the Ecwid embed widget approach works immediately in Bolt's WebContainer preview. The widget loads from Ecwid's CDN and does not require an incoming server connection. REST API calls to Ecwid's endpoint also work in the preview since they are outbound HTTPS requests. The only Ecwid feature that requires deployment is incoming order webhooks from Ecwid to your server.
Does Ecwid handle payment processing, or do I need to add Stripe?
Ecwid handles payment processing for you through its built-in checkout. Ecwid integrates with PayPal, Stripe, Square, and 40+ other payment providers — you connect your payment account in the Ecwid dashboard, not in your Bolt code. When customers click Buy, they complete checkout on Ecwid's hosted checkout page or your configured custom domain, with payment handled by Ecwid.
How is Ecwid different from Shopify for a Bolt.new integration?
Ecwid is specifically designed to be embedded into existing websites via a JavaScript snippet — it was built for this use case. Shopify is a full hosted platform with a Storefront API for headless commerce, but its API integration is more complex. Ecwid's embed approach requires fewer lines of code for a working storefront, making it faster to implement in Bolt.new.
What happens to the Ecwid store widget when users navigate away in my app?
The Ecwid widget stores cart data in the browser's localStorage, so items added to the cart persist when users navigate between pages and return to the shop. However, you should always clean up the Ecwid script tag in your React component's useEffect cleanup function to prevent duplicate script loading when the component remounts.
Can I use Ecwid's REST API to create orders programmatically?
Yes — the Ecwid REST API supports creating orders via POST /orders with full control over line items, customer data, payment status, and fulfillment. This is useful for scenarios where you want to create an order in Ecwid after payment is handled externally. Use your secret key for order creation API calls, always from server-side API routes.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation