To integrate Printful with Lovable, create Supabase Edge Functions that proxy calls to the Printful API for product catalog access, mockup generation, and order fulfillment. Store your Printful API key in Cloud Secrets. This lets you build a print-on-demand storefront in Lovable where customers browse products, see mockups, and place orders that Printful automatically prints and ships.
Build a Print-on-Demand Storefront in Lovable Powered by Printful
Print-on-demand is one of the most popular business models for creators, artists, and brand owners: design products once, let customers order them, and Printful handles printing, packing, and worldwide shipping automatically. Building your storefront in Lovable gives you full creative control over the customer experience — custom design, layout, checkout flow — while Printful handles all the physical fulfillment in the background.
The integration requires Edge Functions because Printful's API requires authentication. Every API call (fetching products, generating mockups, placing orders) must route through a server-side Edge Function that authenticates with your Printful API key stored in Cloud Secrets. Your React storefront calls the Edge Function, which forwards the request to Printful's API at api.printful.com and returns the result.
Printful's API covers four main capabilities relevant to a storefront: the Catalog API for browsing available blank products and their variants (t-shirts, hoodies, mugs, etc.), the Mockup Generator API for generating product preview images with your custom design applied, the Shipping API for calculating shipping rates by destination, and the Orders API for placing and tracking orders. This guide walks through setting up all four, giving you a complete print-on-demand pipeline from product discovery to order fulfillment.
Integration method
Printful integration in Lovable uses Supabase Edge Functions to proxy API calls to Printful's REST API. Your Printful API key is stored in Cloud Secrets and accessed via Deno.env.get() inside the Edge Function — never exposed to the browser. The Edge Function handles product catalog fetches, mockup generation requests, shipping rate calculations, and order placement with Printful. React components in Lovable call the Edge Function to retrieve data and trigger fulfillment.
Prerequisites
- A Printful account at printful.com — free to create, no subscription required to access the API
- Your store's design files or artwork for the products you plan to sell
- A Lovable project with Lovable Cloud enabled
- A payment processing solution (Stripe recommended via Lovable's native connector) to collect payment before placing orders with Printful
- Understanding that Printful charges you (the store owner) at their wholesale price when an order is placed — you set retail prices higher to earn profit
Step-by-step guide
Generate a Printful API key
Generate a Printful API key
Log in to your Printful account at printful.com and navigate to Settings → Stores. Select the store you want to connect or create a new store by clicking 'Add new store'. Once in your store settings, go to the 'API' tab (sometimes listed as 'Printful API'). Click 'Generate API Key' or 'Create API Token'. Give your token a name like 'Lovable Storefront' and select the scopes your integration needs. For a storefront, you need at minimum: orders:read and orders:write (to place and check orders), catalog:read (to browse available products), and mockup_generator:write (to generate product mockups). Copy the generated token immediately — Printful shows the full token only once after generation. If you are working with a Printful API for an established store, you can also use the OAuth flow to let your customers authenticate with their own Printful stores, but API key authentication is simpler for a single-store setup.
Pro tip: Printful also supports OAuth2 for multi-store applications. For a single-store storefront, API key authentication is simpler and sufficient.
Expected result: You have a Printful API token copied and ready to store in Cloud Secrets.
Add the Printful API key to Cloud Secrets
Add the Printful API key to Cloud Secrets
In your Lovable project, click the '+' icon next to Preview to open the Cloud tab, then navigate to the Secrets section. Add a secret named PRINTFUL_API_KEY and paste your Printful API token as the value. The secret is immediately encrypted and accessible only from your Edge Functions via Deno.env.get('PRINTFUL_API_KEY'). Never paste a Printful API key in a Lovable chat message or in your React component code — Lovable's free tier chat history is publicly visible, and your Printful account could be accessed by anyone who sees the key. The security layer in Lovable Cloud blocks approximately 1,200 private API keys per day from being accidentally hardcoded into application code, and this SOC 2 Type II certified secrets management system is your protection against that. Your API key is encrypted at rest and in transit and never appears in any browser-accessible code or network request from your frontend.
Pro tip: If you need to test with a Printful test environment or a different store, create a separate secret PRINTFUL_API_KEY_TEST so you can easily switch between environments.
Expected result: PRINTFUL_API_KEY appears in your Cloud Secrets panel.
Create the Printful API proxy Edge Function
Create the Printful API proxy Edge Function
Ask Lovable to create a Supabase Edge Function that proxies requests to Printful's REST API at https://api.printful.com. Printful's API uses Bearer token authentication — the Authorization header should be 'Bearer YOUR_API_KEY'. The Edge Function should accept a 'path' query parameter mapping to a Printful endpoint (e.g., /catalog/products, /mockup-generator/create-async/{product_id}, /orders), and for POST requests, forward the request body to Printful. The Edge Function needs to handle CORS for browser calls, read PRINTFUL_API_KEY from Deno.env.get(), and return Printful's JSON response. Printful's API base URL is https://api.printful.com — there is no sandbox mode for the API itself, but you can use test mode by adding X-PF-Store-Type: store header. All API responses are wrapped in a result key: { code: 200, result: { ... } }.
Create a Supabase Edge Function called printful-proxy that proxies requests to the Printful API. Read PRINTFUL_API_KEY from Deno.env.get(). Accept a 'path' query parameter for the endpoint. Use Bearer token auth in the Authorization header. Forward POST request bodies to Printful. Return Printful's JSON response with CORS headers. The Printful base URL is https://api.printful.com.
Paste this in Lovable chat
1import { serve } from "https://deno.land/std@0.168.0/http/server.ts";23const corsHeaders = {4 "Access-Control-Allow-Origin": "*",5 "Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",6};78serve(async (req) => {9 if (req.method === "OPTIONS") {10 return new Response("ok", { headers: corsHeaders });11 }1213 try {14 const apiKey = Deno.env.get("PRINTFUL_API_KEY");15 if (!apiKey) {16 return new Response(17 JSON.stringify({ error: "PRINTFUL_API_KEY not configured" }),18 { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }19 );20 }2122 const url = new URL(req.url);23 const path = url.searchParams.get("path") || "/catalog/products";24 url.searchParams.delete("path");2526 const printfulUrl = new URL(`https://api.printful.com${path}`);27 url.searchParams.forEach((value, key) => {28 printfulUrl.searchParams.set(key, value);29 });3031 const requestOptions: RequestInit = {32 method: req.method,33 headers: {34 "Authorization": `Bearer ${apiKey}`,35 "Content-Type": "application/json",36 },37 };3839 if (req.method !== "GET" && req.method !== "HEAD") {40 requestOptions.body = await req.text();41 }4243 const response = await fetch(printfulUrl.toString(), requestOptions);44 const data = await response.json();4546 return new Response(JSON.stringify(data), {47 status: response.status,48 headers: { ...corsHeaders, "Content-Type": "application/json" },49 });50 } catch (error) {51 return new Response(52 JSON.stringify({ error: error.message }),53 { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }54 );55 }56});Pro tip: Printful wraps all successful responses in a 'result' key. In your React components, access data.result to get the actual payload.
Expected result: The printful-proxy Edge Function is deployed. Cloud → Logs should show successful invocations.
Build the product catalog and mockup display
Build the product catalog and mockup display
Ask Lovable to create React components that fetch Printful's product catalog and display products with their variants. The Printful Catalog API at /catalog/products returns all available blank products (t-shirts, hoodies, mugs, etc.) with their IDs, names, and thumbnail images. To get detailed information including all size and color variants for a specific product, call /catalog/products/{product_id}. For mockup generation, you need to call the Mockup Generator API. First call /mockup-generator/create-async/{product_id} with a POST body containing your design file URL and the variant IDs you want mockups for. This starts an async mockup generation task. Then poll /mockup-generator/task?task_key={task_key} until the task status is 'completed', at which point the response contains the mockup image URLs. Store completed mockup URLs in Supabase so you do not regenerate them on every page load — mockup generation is rate-limited and takes several seconds per request.
Create a PrintfulProductCard component that shows a Printful product with mockup image, name, available sizes, and price. Fetch the product details from my printful-proxy Edge Function using path=/catalog/products/{id}. Display the product variants for size selection. Add a 'Generate Mockup' button that calls /mockup-generator/create-async/{id} with a design image URL, polls for completion, and displays the mockup image when ready.
Paste this in Lovable chat
Pro tip: Store generated mockup image URLs in Supabase after the first generation. Printful mockup generation can take 10-30 seconds and has rate limits — never regenerate mockups you already have stored.
Expected result: Products display from Printful's catalog with variant selectors, and mockup images generate and display after a brief loading period.
Implement order placement with Printful
Implement order placement with Printful
When a customer completes checkout (using Stripe via Lovable's native connector or another payment method), create a Printful order via the Edge Function. The Printful Orders API at /orders accepts a POST request with a recipient object (name, address, city, country, zip) and an items array (each item has sync_variant_id or variant_id, quantity, and your retail price). For an unconfirmed order (draft mode), set confirm: false in the request — this is useful for reviewing orders before Printful charges you and starts production. For automatic fulfillment, set confirm: true. Printful will charge your account balance or connected payment method when the order is confirmed. Implement a Supabase Edge Function trigger or a scheduled function to poll /orders and sync order status updates (pending, in_process, fulfilled, canceled) back to your Supabase orders table. Store Printful order IDs alongside your own order records so you can track fulfillment status and provide customers with shipping tracking numbers when Printful ships their order.
Create an Edge Function called place-printful-order that accepts order details (recipient address, items with Printful variant IDs and quantities) and places a confirmed order with Printful via POST to /orders. Save the Printful order ID, status, and shipping tracking to a Supabase orders table. Also create an order status check function that calls /orders/{id} and updates the status in Supabase.
Paste this in Lovable chat
Pro tip: Always start with confirm: false (draft orders) during development and testing. Printful will not charge your account or start production until you confirm the order.
Expected result: Customers can complete checkout and their order is automatically placed with Printful for fulfillment, with order status synced back to your Supabase database.
Common use cases
Print-on-demand merchandise store for creators
Creators (artists, YouTubers, podcasters) sell custom branded merchandise — t-shirts, hoodies, mugs, phone cases — through a Lovable storefront. Customers browse products with Printful mockups showing the creator's design, add items to cart, and checkout. Printful handles all printing and shipping automatically.
Build a merchandise store where customers can browse custom t-shirts and hoodies with my logo applied. Fetch available products from Printful via an Edge Function, show product mockups generated by the Printful Mockup Generator, let customers select size and color variants, and place orders through Printful's API. Sync new orders to a Supabase orders table.
Copy this prompt to try it in Lovable
Custom photo product shop
Allow customers to upload their own photos and preview them on Printful products like canvas prints, posters, or photo mugs. The Mockup Generator API accepts a customer's image URL and returns a photorealistic preview of their product before they order.
Create a custom photo product page where users upload an image, choose a product (canvas print, poster, mug), and see a real-time mockup of their photo on the product using the Printful Mockup Generator API. Show a preview image and let them select size before adding to cart.
Copy this prompt to try it in Lovable
Wholesale catalog browser for brand teams
Internal tool for brand teams to browse Printful's full catalog, compare product variants, check base costs and shipping rates, and plan which products to offer. Shows Printful's catalog data including product specifications, print area dimensions, and pricing.
Build a Printful product catalog browser that fetches all available products using the Printful Catalog API. Display products organized by category with variant options for size and color. Show base cost, available print techniques, and print area dimensions. Add a shipping calculator that takes a destination country and calculates fulfillment cost.
Copy this prompt to try it in Lovable
Troubleshooting
Edge Function returns 401 Unauthorized from Printful
Cause: The PRINTFUL_API_KEY secret is missing, incorrectly named, or the API token has been revoked in your Printful account. The Authorization header must use 'Bearer' prefix, not 'Basic'.
Solution: Verify the secret name in Cloud Secrets is exactly PRINTFUL_API_KEY. Check your Printful account under Settings → API to confirm the token is active and has not been revoked. Verify your Edge Function code uses Authorization: Bearer ${apiKey} not Authorization: Basic ${apiKey}.
1"Authorization": `Bearer ${apiKey}`,Mockup generation returns task status 'failed' or never completes
Cause: The design image URL is not publicly accessible, has an unsupported format, or the image dimensions do not meet Printful's minimum requirements. Printful's mockup generator requires images to be accessible via public HTTP/HTTPS URLs — local file uploads or data URIs do not work.
Solution: Upload your design images to Supabase Storage with public bucket access, or use any public CDN URL. Printful requires design files to be at least 300 DPI at print size, in PNG, JPG, or SVG format. Check the task error message in the failed response for specific rejection reasons.
Order placement fails with 'Insufficient funds' error
Cause: Your Printful account billing does not have sufficient credit to fulfill the order. Printful charges the store owner's payment method when an order is confirmed.
Solution: Add a payment method or credit to your Printful account under Settings → Billing. For production stores, enable Printful's automatic billing to charge your card when orders are placed. During development, use confirm: false to create draft orders without charging your account.
Printful catalog returns products but with no variants or empty size options
Cause: The /catalog/products endpoint returns only basic product information. Detailed variant data (all sizes, colors, pricing) requires a separate call to /catalog/products/{product_id}/variants.
Solution: Make a separate Edge Function call to /catalog/products/{product_id}/variants to get the full variant list for each product. Cache variant data in Supabase since Printful's catalog rarely changes, then display size and color options from the cached variants rather than making an API call on every product page load.
Best practices
- Generate product mockups once and store the resulting image URLs in Supabase — never regenerate mockups that you already have cached, as Printful's mockup generator is rate-limited and slow
- Use Printful draft orders (confirm: false) during development and testing to avoid triggering production fulfillment and charges before your storefront is ready
- Sync your Printful product catalog to Supabase on a scheduled basis (daily is sufficient) rather than fetching it fresh on every storefront page load — the catalog changes infrequently
- Always collect payment via Stripe before placing the order with Printful — place the Printful order only after payment is confirmed, not before, to avoid fulfillment costs on failed payments
- Store Printful order IDs in your Supabase orders table alongside your own order IDs so you can look up fulfillment status and tracking numbers by querying /orders/{printful_order_id}
- Handle Printful's shipping rate calculation before checkout by calling /shipping/rates with the customer's destination address — display shipping cost to customers and include it in the Stripe payment amount
- Add webhook handling for Printful events (package_shipped, order_failed) using an Edge Function as the webhook receiver to automatically update order status in your Supabase database
Alternatives
WooCommerce is a full storefront platform for selling any products, whereas Printful is specifically a fulfillment service — if you need a complete e-commerce platform rather than just fulfillment, WooCommerce integrates directly with Printful as a plugin.
Shopify is a native Lovable connector and has a direct Printful app integration, making the Shopify + Printful combination simpler to set up than a custom Lovable + Printful build if you prefer a traditional storefront approach.
eBay API lets you list Printful-fulfilled products on eBay's marketplace, reaching eBay's existing buyer base rather than driving traffic to your own branded storefront.
Frequently asked questions
Do I need to pay Printful to start building my integration?
No. Creating a Printful account and accessing the API is free. Printful only charges you when a real order is placed and confirmed for production. API access, catalog browsing, and even mockup generation are free. You pay Printful's wholesale product cost only when a customer orders.
Can customers upload their own designs to put on Printful products?
Yes. The Printful Mockup Generator API accepts a placement_option with an image_url parameter — this image URL can be a file your customer uploaded to Supabase Storage. Upload the customer's design file to a public Supabase Storage bucket, get the public URL, then pass it to the Mockup Generator API to generate a preview of their custom product.
How long does Printful mockup generation take?
Mockup generation is asynchronous and typically takes 5-30 seconds per request. The API returns a task_key immediately, and you poll /mockup-generator/task?task_key={key} until status is 'completed'. This is why caching mockup image URLs in Supabase is essential — regenerating mockups on every page load would create very slow product pages.
Does Printful have a test or sandbox mode?
Printful does not have a separate sandbox environment. However, you can create draft orders (confirm: false) during development which do not trigger production or billing. For testing the full order flow, place small test orders with confirm: true using real products, then cancel them immediately from your Printful dashboard to get a refund of the wholesale cost.
Can I use this integration to manage an existing Printful store with already-synced products?
Yes. The Printful Store Products API (/store/products) lets you access products that are already configured in your Printful store with your designs applied and retail prices set. This is different from the Catalog API which shows blank products. Use /store/products to display your actual store's product listings, which already have mockup images, pricing, and variants configured in your Printful dashboard.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation