<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Наталья Решетникова</title>
    <description>The latest articles on DEV Community by Наталья Решетникова (@natalia_weblevo).</description>
    <link>https://dev.to/natalia_weblevo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4161840%2F15b55098-56e7-4c78-a892-89f9d345c960.jpg</url>
      <title>DEV Community: Наталья Решетникова</title>
      <link>https://dev.to/natalia_weblevo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/natalia_weblevo"/>
    <language>en</language>
    <item>
      <title>We built an AI design SaaS for small businesses in two months: Next.js, Supabase, Stripe as merchant of record, fal.ai</title>
      <dc:creator>Наталья Решетникова</dc:creator>
      <pubDate>Sun, 04 Oct 2026 14:54:30 +0000</pubDate>
      <link>https://dev.to/natalia_weblevo/we-built-an-ai-design-saas-for-small-businesses-in-two-months-nextjs-supabase-stripe-as-1297</link>
      <guid>https://dev.to/natalia_weblevo/we-built-an-ai-design-saas-for-small-businesses-in-two-months-nextjs-supabase-stripe-as-1297</guid>
      <description>&lt;p&gt;&lt;em&gt;Case study from Weblevo, a two-person web studio in Madeira. Brifora is our own product, so this is the honest version.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;My co-founder runs a print and embroidery shop. Every week someone brings a phone photo of a logo and asks for it on a t-shirt. The file is a 400-px JPG; the embroidery machine needs a vector; the customer has no designer and no budget for one. We built &lt;strong&gt;&lt;a href="https://brifora.app/?utm_source=devto" rel="noopener noreferrer"&gt;Brifora&lt;/a&gt;&lt;/strong&gt; to turn "what the customer already has" into files that print.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create:&lt;/strong&gt; logo from a 6-question brief (4 variants, SVG from the start), product images, short video from a still.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; background removal, new scene, 4× upscale, outpaint to banner format, object removal, free captions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Brand:&lt;/strong&gt; logo mockups on 8 products with a free position/curve editor, "more in this style" series, raster → SVG, brand kit, cross-stitch pattern from any image (yes, really — the shop does embroidery).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Credits-based pricing from €9/month. Four interface languages: EN, PT, UK, RU.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js 16&lt;/strong&gt; on Vercel (App Router, server actions, edge route for OG images)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supabase&lt;/strong&gt; — Postgres, auth by email code, storage, RLS everywhere&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stripe Managed Payments&lt;/strong&gt; — Stripe is merchant of record, so EU VAT, invoices and disputes are theirs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fal.ai&lt;/strong&gt; — one gateway to all generation models (image, vector, video, and a small text model for the assistant)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resend&lt;/strong&gt; for email, &lt;strong&gt;ElevenLabs&lt;/strong&gt; for the assistant's recorded voice, &lt;strong&gt;Vercel Analytics&lt;/strong&gt; (no cookies, no banner)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Five decisions worth stealing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Every generation is a job.&lt;/strong&gt; The browser enqueues; fal.ai calls a signed webhook on completion; a one-minute cron sweeps stragglers and refunds credits on provider failure. The user can close the tab. Video made this mandatory, but it fixed image flows too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The model draws the blank; code places the logo.&lt;/strong&gt; Asking a model to "put this logo on a mug" mangles the logo. We render an empty product, then composite the user's actual file with sharp — crisp, editable, and the "nudge it 20 px left" editor is free because no model is involved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Prices live in one table.&lt;/strong&gt; Every card, every page, every FAQ answer reads credit costs from the same source. We changed prices three times before launch and never had a stale number.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Language in the URL, not in a cookie.&lt;/strong&gt; We launched with cookie-based language and Google indexed only English. Moving to &lt;code&gt;/pt/&lt;/code&gt;, &lt;code&gt;/uk/&lt;/code&gt;, &lt;code&gt;/ru/&lt;/code&gt; prefixes with hreflang took a day and was the single most important SEO change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Launch mode as an env var.&lt;/strong&gt; &lt;code&gt;LAUNCH_MODE=open&lt;/code&gt; flipped the "coming soon" banner off at launch without a redeploy. Boring, and exactly what you want on launch day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things that bit us
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;allow_promotion_codes&lt;/code&gt; and &lt;code&gt;discounts&lt;/code&gt; are mutually exclusive in Stripe Checkout. We apply the code server-side when the user typed one, and let Stripe show the field when they didn't.&lt;/li&gt;
&lt;li&gt;Satori (next/og) can't render a 50-path SVG character; our OG cards are typographic.&lt;/li&gt;
&lt;li&gt;Headless browsers are filtered by Vercel Analytics as bots — test tracking with a real user agent or you'll think it's broken.&lt;/li&gt;
&lt;li&gt;fal.ai's &lt;code&gt;bria/expand&lt;/code&gt; wants absolute canvas dimensions, not a ratio.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Timeline
&lt;/h2&gt;

&lt;p&gt;First commit to public launch: about two months, one product owner, AI-assisted development (Claude Code did most of the typing; we did the deciding). Roughly 40 screens, tools and integrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Product: &lt;a href="https://brifora.app/?utm_source=devto" rel="noopener noreferrer"&gt;https://brifora.app/?utm_source=devto&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Examples: &lt;a href="https://brifora.app/examples" rel="noopener noreferrer"&gt;https://brifora.app/examples&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The studio: &lt;a href="https://weblevo.com" rel="noopener noreferrer"&gt;https://weblevo.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Questions about the stack are welcome in the comments — happy to go deeper on the job queue or the Stripe MoR setup.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>saas</category>
      <category>nextjs</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
