Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with Ecwid (Lightspeed E-Series)

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.

What you'll learn

  • How to embed the Ecwid storefront widget in a React component for a zero-code instant store
  • How to use the Ecwid REST API to fetch products and build a custom product grid
  • How to customize the Ecwid embed appearance using CSS overrides and JavaScript configuration
  • How to handle cart and checkout events from the Ecwid widget in your React app
  • How to deploy your Ecwid-powered storefront to Netlify or Bolt Cloud
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate15 min read20 minutesE-commerceApril 2026RapidDev Engineering Team
TL;DR

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

Bolt Chat + API Route

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

1

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.

Bolt.new Prompt

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

src/lib/ecwid.ts
1// src/lib/ecwid.ts
2const STORE_ID = process.env.NEXT_PUBLIC_ECWID_STORE_ID;
3const BASE_URL = `https://app.ecwid.com/api/v3/${STORE_ID}`;
4
5export 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');
11
12 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 });
20
21 if (!response.ok) {
22 throw new Error(`Ecwid API error ${response.status}: ${await response.text()}`);
23 }
24
25 return response.json();
26}
27
28export 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.

2

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.

Bolt.new Prompt

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

app/shop/page.tsx
1// app/shop/page.tsx
2'use client';
3import { useEffect } from 'react';
4
5export default function ShopPage() {
6 const storeId = process.env.NEXT_PUBLIC_ECWID_STORE_ID;
7
8 useEffect(() => {
9 if (!storeId) return;
10
11 // Configure Ecwid before loading script
12 (window as any).ec = (window as any).ec || {};
13 (window as any).ec.config = {
14 baseUrl: '/shop',
15 storefrontUrls: { cleanUrls: true },
16 };
17
18 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);
23
24 return () => {
25 // Clean up on unmount
26 const existingScript = document.getElementById('ecwid-script');
27 if (existingScript) document.body.removeChild(existingScript);
28 delete (window as any).ecwid_onBodyDone;
29 };
30 }, [storeId]);
31
32 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.

3

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.

Bolt.new Prompt

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

app/api/ecwid/products/route.ts
1// app/api/ecwid/products/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { ecwidFetch } from '@/lib/ecwid';
4
5interface 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}
17
18interface EcwidProductsResponse {
19 items: EcwidProduct[];
20 total: number;
21 count: number;
22 offset: number;
23 limit: number;
24}
25
26export 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 });
35
36 try {
37 const data = await ecwidFetch<EcwidProductsResponse>(
38 `products?${query}`,
39 { next: { revalidate: 300 } } as any // 5 minute cache
40 );
41
42 const products = data.items
43 .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 }));
54
55 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.

4

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.

Bolt.new Prompt

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

app/globals.css
1/* app/globals.css — Ecwid widget customization */
2
3/* Match app typography */
4.ecwid,
5.ec-storefront {
6 font-family: inherit !important;
7}
8
9/* 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}
15
16.ec-cart__checkout-button:hover,
17.ec-storefront .form-control__button--primary:hover {
18 background-color: #1d4ed8 !important;
19}
20
21/* Hide Ecwid footer on free plan */
22.ec-footer {
23 display: none !important;
24}
25
26/* 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.

Bolt.new Prompt

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.

Bolt.new Prompt

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.

Bolt.new Prompt

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}'.

typescript
1// The div ID must exactly match 'my-store-' + your store ID
2// 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

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.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.