How to build an AI content studio with v0
Your own content studio, built in the browser and wired to a real database. The library and the preview frames come first, then the database, then the generation calls behind your own provider key, each described in its own chat and committed to a branch you review before merging.
v0
$ Build the screens for a content studio: a dashboard, an asset library grid, a generate-image panel, an image detail and edit view, a post builder with five platform previews, and a brand kit page, then connect a database and the server-side routes that make the generation real.
- Library and frames sketched
- Generation and ceiling wired
- Ready to merge
What an AI content studio actually is
An AI content studio relies on three core components: the prompt box, asset storage, and social previews. The prompt box is the part everyone demonstrates and the easiest to build. However, proper storage and platform previews are what actually decide whether you keep using the tool next week.
Underneath the hood, this application performs four basic tasks: asking a model for an image, asking a model for text, saving both where you can easily find them again, and displaying how they will look on external platforms. Generating text and images takes only a few hours of work each, which is why every demo focuses on them: they are simply not where the real technical challenge lies.
The real difficulty is that AI outputs are only valuable within a structured system. A single image from a clever prompt is just a party trick. A real tool gives you hundreds of searchable assets that retain their creation prompts, match your brand’s colors and voice, and fit the exact layout of every social network. Everything hard about this build comes down to creating that system.
Finally, this is the first application where every generation costs real money on the spot. Unlike a fixed monthly subscription, pay-per-press charges can quickly add up if an enthusiastic user spends an afternoon experimenting. This single financial reality fundamentally changes how you build the application, requiring strict budget caps rather than simple user access.
The library is the product, not the prompt box
Generation is stateless and cheap to demonstrate. What you actually need is everything after it: the file stored somewhere durable, the prompt kept beside the result so you can make another like it, a type and a size you can filter on, and uploads sitting alongside generated work as equals. Build the library first and the prompt box becomes a button on it.
A preview is a promise about somebody else’s renderer
Five networks crop, compress and truncate differently, and a preview that is approximately right is worse than none. It is a promise that the thing you post will look like the thing you approved. Decide which platforms you genuinely support, get their aspect ratios and their caption cut-offs right for those, and say nothing about the rest.
Authentication isn’t budget control
Requiring somebody to sign in stops strangers. It does not stop a colleague, a loop, or an over-eager retry from spending real money, because every generation is a charge on your card. The cap is not a nice-to-have you add when the bill surprises you. It belongs in the first week, and nothing else in this build is as easy to regret leaving out.
What renting the generations gets you
5
AI credits a month on the entry plan of Later, a well-known scheduling tool, at $18.75 a month billed yearly, and its own page explains that "1 credit generates 3 ideas or 1 caption". So the plan includes five captions a month. Its next tiers include 50 and 100. Read on Later’s pricing page in August 2026. What you are renting in this category is not the software, it is permission to call the model.
later.com pricing page, read August 2026 · checked August 2026
The parts every content studio is built from
The first two are what everybody demonstrates. The other four are why you would still be using it in three months.
Save files to your own storage
The request itself is a few lines. The part worth building carefully is what happens to the result: providers hand images back in more than one shape (some as base64 in the response body, some as a URL that expires) so the code has to cope with both and write the bytes into storage you control. Skip that and your library is a wall of dead links a fortnight later, which is the single most common way a working demo becomes an unusable tool.
Generate multiple caption variants
A model given one caption to write will write one confident caption, and you will accept it because rejecting it means starting again. Ask for three variants, store them all against the post, and mark the one you chose. The choosing is where the quality comes from, and keeping the alternatives is what lets you learn which kind of phrasing you actually pick.
Embed a fixed brand kit
Colours, a logo and a description of how you sound, stored once and sent with every request. Without it a model produces competent content that belongs to nobody, and you will spend longer editing that than you would have spent writing from scratch. This is the cheapest quality upgrade in the whole application and it is usually the last thing people add.
Save prompts alongside assets
Type, size, when it was made, whether it was generated or uploaded, and (the one people forget) the prompt that produced it, kept beside the result. That last field is what turns a folder into something you can work from, because the most useful thing about a picture you like is being able to ask for another one like it.
Build accurate social previews
Each platform has its own aspect ratios, its own caption truncation and its own idea of a safe area. A frame that is roughly right is a promise you will break at the moment of posting. Support the platforms you genuinely use, get those exactly right, and give yourself a file you can actually publish rather than a picture of one.
Set hard API spending caps
Every other feature here costs you once, at build time. This one costs you per press, forever, and the charge lands on your card rather than a customer’s. So the application needs three things a demo never has: a record of every generation including the image ones, a limit per person over a window you choose, and a total you can watch. Requiring a login is not a limit. It only decides whose enthusiasm is spending the money.
Build your own AI studio vs Renting monthly credit bundles
Most SaaS tools mark up AI costs by selling limited monthly credit bundles. Using your own provider key removes vendor markups and arbitrary caps entirely, giving you total cost control, provided you set your own spending limits.
Build your own
Your own key means you pay the model’s list price per generation and stop when you decide to. No credit bundles, no monthly floor before the first image, and no plan tier standing between you and the feature you were paying for.
- Generations cost what the provider charges, with nobody’s margin on top
- A busy week is a bigger provider bill rather than an upgrade you cannot postpone
- Your brand kit and your library sit in your own database, not inside somebody’s workspace
- Swapping to a cheaper or better model is a configuration change, not a wait for a roadmap
- The assets are files in your own storage, so nothing has to be exported to be kept
- How many generations a person gets is a rule you write, not a bundle you buy
Rent the studio
Later · Predis.ai · Buffer · Ocoya · Copy.aiWhat renting buys, and this template genuinely does not have: the connection to the networks. All four of the social products schedule and publish for you. They hold the OAuth tokens, handle each platform’s API, retry a failed post and tell you when something went out. This template previews five networks and posts to none of them.
- They actually publish: tokens, schedules, retries, and a calendar of what goes out when
- Analytics after the fact, which needs the platform connection this template does not have
- A credit bundle is also a spending ceiling, and a build with your own key has none until you write one
- Working the day you sign up, with the platform quirks and the aspect ratios already handled
- Somebody else’s problem when a network changes its API or its image sizes
- Approval flows, calendars and team seats, none of which this single-workspace template attempts
First because it states this section’s argument better than we could. Its page explains the unit: AI credits are "used to power Later’s AI features: Ideas and Caption Writer. 1 credit generates 3 ideas or 1 caption." Five credits is five captions a month. The rest of the plan is a scheduler. Starter is one social set of 8 profiles, one user, and "Schedule up to 30 posts per profile", which is the honest reading of what you are buying: publishing, with the AI as a garnish. Annual billing is advertised as "3 months free | 25% off". The page showed us yearly-billed figures only, so no month-to-month rate is quoted.
later.com · checked August 2026
The most useful row for doing the arithmetic, because it converts credits into generations on its own page: Core is "Generate ~86 AI images, ~9 videos". So $19 buys roughly eighty-six images, and the ladder above it buys "~213" and "~666". Team members are unlimited on every tier, which tells you the meter is generations rather than people. It publishes too, and covers 10, 20 and 60 social accounts respectively. Hold the $19-for-86-images figure against your own provider’s per-generation price. That comparison is the entire build-versus-buy decision in this category.
predis.ai · checked August 2026
Here for a different meter and a useful reality check. Buffer barely rations AI at all (the AI Assistant is in the free tier) and charges per connected channel instead, which is a reminder that the thing most of this market sells is the connection rather than the generation. Its free plan is genuinely usable for one person: "10 scheduled posts per channel - refill anytime", "100 ideas", "1 user account", up to three channels. If what you actually want is scheduling to three accounts and you are relaxed about writing your own captions, this is the row that says do not build anything.
buffer.com · checked August 2026
Included for what it does not tell you, which is worth as much as a price. The tiers are listed as plain counts ("Workspaces, 1, Users, 1, Social profiles, 5, Credits, 100") and nowhere does the page say what a credit buys. So 100 credits for $15 cannot be turned into a number of images, and any comparison you make with it is a guess. The Diamond tier’s credit allowance was not in what the page served us, and its annual prices are advertised at 20% off without the adjusted figures being shown, so neither is quoted here. There is a 7-day trial.
ocoya.com · checked August 2026
The row furthest from this template’s job, and in the table for the shape of its ladder rather than a like-for-like comparison. It is a go-to-market copy platform rather than a caption writer, so read the $29 tier as "unlimited words in chat across five seats" and not as a social tool. What makes it instructive is the cliff: nothing between $29 and $1,000 a month, no free plan listed, and the credits only appear at the tier where the price becomes a procurement decision. That gap is a fair picture of what happens when a category prices for teams rather than for a person with a brand.
copy.ai · checked August 2026
Rule of thumb: if what you need is posts going out on a schedule to several accounts, with analytics afterwards and somebody else absorbing each platform’s API changes, rent, and Buffer’s free tier in particular is hard to argue with for one person and three channels. If what you need is a lot of generations in your own brand, kept in your own library, at the provider’s price rather than a credit bundle’s, that is the half worth owning. The comparison that decides it is arithmetic you can do in a minute: work out how many images you would actually generate in a month, price them at your provider’s rate, and hold that against $19 for about eighty-six. Below a few dozen, renting wins on effort alone. Well above it, the credit bundles are the expensive part, and the thing you have to build in exchange is the ceiling those bundles were quietly providing.
Why build with v0
v0 starts with the screens: forms, tables, dashboards, whatever the interface needs, generated in React and Next.js from a plain description. That’s the part most people notice first, because it’s fast and it looks finished immediately.
The backend isn’t automatic in the same way. v0 can write it too, meaning Next.js routes and server logic that read and write real data, but you ask for it, usually once the UI already exists and there’s something real to connect it to:
Sketch
Describe the screen or component you want.
Preview
See it rendered live, and select any part of it to adjust directly.
Connect
Add a database and the routes that read and write to it, once the UI needs somewhere real to save.
Iterate
Prompt again for the next screen or the next piece of logic.
The order matters here more than with a full-app builder: v0 gets you a finished-looking interface fast, and the data underneath doesn’t show up until you ask for it and give it somewhere to live.
One clickconnects a database
Supabase, Neon, and Upstash are integrations you add from the project menu once a screen needs to hold onto something real, and v0 provisions the credentials and writes the routes that use them.
Live preview is the feedback loop
Every prompt updates the working interface right there in the chat, so you see the actual screen changing instead of imagining it from a description.
Design mode edits without a prompt
Select an element in the live preview, adjust its style directly or type a plain-language instruction, and v0 applies the change back to the real source code as a new version.
Pay a developer, or do it with AI
Compare the true upfront and running costs of hiring a developer versus building with an AI tool. Because model APIs charge per generation, both paths require you to implement custom spending limits.
Hire a developer
Custom build, from scratch- Developer
- ~$9.3k-$37k
- Supabase (backend)
- Free tier · $25/mo (Pro plan)*
- Hosting
- $0 free tier
- Model provider
- Per generation - the line that moves with use
- Build time
- ~185 hrs of their work
~$9.3k-$37k to build, then from $25/mo plus what you generate
Our ~185-hour estimate, priced at the rates in the survey linked below: senior US developers at $100-$150+ an hour, and agencies charging 20-40% above the freelancers they bid against, which is where $50/hr and $200/hr come from. Where those hours go is not where a quote usually assumes. The two generation calls are a fortnight between them. The library, the brand kit, five accurate previews and the spend ceiling are the rest. If somebody has quoted you for "an AI image generator", check which of those four they costed.
Build it with v0
From scratch, with v0- v0
- $0 ($5/mo of credits) to $30+/month (Plus)
- Backend (Supabase)
- Free tier · $25/month (Pro plan)*
- Hosting (Vercel)
- Free on Vercel’s Hobby plan
- Your time
- ~89 hrs
Free to try the idea, ~$30+/month on Plus while you build a real one, then whichever plan you keep using
v0 bills in dollars of credit rather than a flat fee, so cost tracks usage: importing the pre-built template can fit inside Free’s $5 a month, while a from-scratch build runs into Free’s 7-messages-a-day cap quickly and usually needs Plus, at $30 per user per month with no annual discount shown. Because v0 generates the interface and the backend as separate steps rather than one pass, expect more prompts to reach the same result than a tool that writes both together.
* On this template the free-tier line to watch is the 1 GB of file storage rather than the database. Generated images accumulate faster than anything else in this catalogue, and a few hundred of them will pass it. Pro, from $25/mo, takes file storage to 100 GB (then $0.0213 per GB) and egress to 250 GB (then $0.09 per GB), and keeps a daily backup for 7 days. It also ends the pause, which matters here for a dull reason: a free project sleeps after a quiet week, and a studio you open when inspiration strikes is exactly the sort that goes quiet.
A credit bundle is the pack of generations a rented studio sells you each month, and neither column above buys one, because your own provider key is billed at the provider’s list price instead. What that leaves is a difference in which line grows. Renting means a monthly floor and a credit allowance that runs out in a busy week, whichever way your usage goes. Owning means a small fixed bill and a provider charge that tracks exactly what you made, cheaper on a quiet month, and genuinely open-ended on a busy one unless you have set a limit. That trade suits somebody making a lot of content, which is the only reason to build this at all.
Prices and rates from supabase.com, developex.com, v0.app, v0.app and vercel.com, checked August 2026.
Decide before you build
Six critical architectural decisions to settle before writing a single line of code, from API budget caps to model flexibility.
How much does a generation cost, and what is your spending cap?
Read your provider’s pricing before you write a line: whether images are priced per image or per token, and whether quality and size change the number. They usually do, by a lot. Then decide the ceiling in words: how many generations per person, over what window, and what somebody sees when they hit it. Decided now it is a field. Decided after the first surprising bill it is a rewrite.
Which AI models will you use, and how easily can you swap them?
Pick a model for images and one for words, then make both a setting rather than a value in the code. Image models are replaced faster than anything else in this stack. If swapping is an environment variable you are fine. If it is a change in four files you will still be on the old one when it stops answering.
Will the app post directly to social media or just export files?
Posting to a network means OAuth per platform, tokens that expire, an API that changes without asking, and a retry queue, more work than everything else in this list combined. Handing over a correctly sized file is a legitimate product, and what this template does. One shapes the export, the other shapes the schema.
How should the AI sound to match your brand voice?
Write the paragraph before you build the brand kit. Writing it is the hard part, the field is easy. Two or three sentences on how you sound, what you never say, and which words you use for your own product. It is sent with every caption request, which makes it the difference between output you post and output you rewrite.
Which social platforms do you actually need to support?
Five previews is what this template ships, not automatically what you need. Each one you claim is a promise about somebody else’s crop, and a wrong promise is worse than a missing one. Pick the networks you genuinely post to, get their sizes and caption limits exactly right, and leave the rest off.
How long will you keep generated assets, and who owns the rights?
Generated assets accumulate, and storage is the line on your bill that only goes up. Decide whether the library is permanent or whether old drafts age out. Then check your provider’s terms on commercial use, and keep the prompt beside every asset: that record is how you answer where an image came from, about a picture in a paid advertisement.
Comparing your build options
A content studio is a small amount of machinery under a lot of interface, which is an unusually good fit for one of these three routes and a trap in another. By hand, on a UI kit with nothing behind the grid, or generated in v0 where the screens arrive first and the model calls follow when you ask.
The generation call is a morning. What takes the months is everything that makes its output usable twice: a library that still makes sense at four hundred images, a brand kit the model actually writes in the voice of, five preview frames that match what each network really does to a picture, and a ceiling on a feature that spends money every time somebody presses it.
A kit gives you a dashboard, a card grid and a modal, which is the shape of this app and none of its substance. Nothing in it knows how to talk to a model, where the generated file goes, what your brand sounds like, that a square crop ruins a portrait photograph, or that one enthusiastic afternoon can cost more than the subscription you were replacing.
The library grid and the five preview frames appear the moment you describe them, and this is the template where that is worth most. They are genuinely most of the product. The database, the generation routes and the ceiling arrive once you ask, each chat landing on a branch of its own.
Estimate your exact build timeframe
Select the features you actually need to calculate your realistic development time. Uncheck items you don’t need or already have to see your hours adjust in real time.
Your estimate
89 hrs
start to finish
Based on the 6 of 6 features you’ve selected, plus ~21h of groundwork. Toggle any on the left to watch the number move, and open the groundwork row to untick what you have already, such as a database that is already running or going live if you are only building a mock-up for now.
A rough estimate, not a quote. Real time depends on how much you customize and how clean your data is.
Let’s set up the tools you need
v0 runs entirely in the browser too, so there’s no download and no terminal. Before step 01: sign up, pick a plan, and know that a database is one click away once a screen actually needs to save something. GitHub is the last piece, and it’s what turns the chat into a project you can hand to someone else.
v0 account
Sign in with a GitHub, Google, or email account and you land in a chat where you describe the interface you want. There’s nothing to install.
Sign up for v0v0 subscription
Free includes $5 of credits a month, capped at 7 messages a day, which is fine for trying a few screens and thin for a real build. Plus is $30 per user per month, billed monthly only (v0’s pricing page shows no annual option), and it’s the realistic floor once you’re iterating past a handful of screens.
Compare v0 plansDatabase (Supabase, Neon or Upstash)
Where your project keeps its data, added when a screen needs one. v0 generates the interface first. A database is a one-click integration you add from the project menu once a screen needs somewhere real to save to, with Supabase, Neon and Upstash as the options, and connecting one lets v0 write the routes that use it.
Connect a database in v0GitHub connection
Not needed to build anything, since v0 keeps its own history of every change. Connect a repository from the chat’s Git panel and v0 also commits every code-changing message to its own branch, ready to merge as a pull request. That is the step that turns the chat into a project other tools, and other people, can use.
Connect v0 to GitHubThe database step is the one worth not skipping once your screens need real data. Everything else here takes a couple of minutes, and after that you’re just describing what you want.
Build your content studio, one chat at a time
The interface comes first with v0 and the backend arrives when asked for, which suits this app better than most in this series. The library and five preview frames really are the bulk of it. The trap is different here too: a generation button that looks finished before any ceiling exists is a button that costs money, so step 03 pairs the call with its limit and step 02 is a hard stop where real data arrives.
- 01
Sketch the library and the five frames, because that is v0’s strength
The interface with placeholder images, in one chat. The point is to look at the grid and the preview frames before anything is stored or generated, and on this app that is genuinely most of the product.
PromptSketch the studio screensBuild the screens for an AI content studio in Next.js with placeholder content for now. A dashboard with recent assets and recent posts. An asset library as a grid with filters for type and source and a detail panel showing an image with the prompt that made it. A generate panel with a prompt box, a size picker and a style picker. A post builder with a title, a caption field, hashtags, and asset selection from the library. A preview area that switches between Instagram, X, Facebook, LinkedIn and TikTok using each network’s real aspect ratios. Include a brand kit page with colour swatches, a logo slot and a text area for the voice. Show me the library grid with about forty placeholder assets so I can see it at a realistic size, and the empty state for a workspace that has generated nothing yet.
Use Design mode for the visual corrections rather than describing them. On this app the grid density and whether the preview frames feel like the real networks are most of the product, and both are far quicker to adjust by pointing than by wording.
- 02
The hard stop: a database, sign-in, and the boundary
Add the integration from the project menu, then get the schema, the accounts and the workspace rules in before another screen exists. Nothing more gets built over placeholders.
PromptModel it and draw the boundaryA Supabase integration is now connected. Three things in this chat and no new screens. First, the schema with a workspace reference on every table: workspaces. Profiles linking an account to exactly one workspace. Assets with a type, a source of generated, ai-edited or uploaded, a storage path, dimensions, a mime type and the prompt that produced it. Posts with a title, caption, hashtags, asset ids and a preview configuration. Caption variants belonging to a post with a primary flag. A brand kit per workspace with colours, a logo path and a voice paragraph. A generations log with the account, model, prompt, size, quality, outcome and estimated cost. Second, email-and-password auth with a workspace and profile created for each new account. Third, row-level security on every table: rows reachable only from the person’s workspace, explicit with-check clauses on inserts and updates, and the profile update policy forbidding a change to which workspace it points at, because that column is what every other policy resolves to. Then replace the placeholder content in the screens I already have with real queries, and prove with two accounts that the second workspace cannot read the first’s assets.
Do not let this chat end with a placeholder still on screen. Everything after it reads real rows, and a library grid designed against forty tidy squares has to be reworked the moment real assets arrive in four aspect ratios with long prompts attached.
- 03
Generation in its own chat, with the ceiling in the same diff
The one place where a tool that leads with interfaces will happily give you a working, unlimited, money-spending button. Ask for the limit in the same breath and read the diff for it.
PromptGenerate one image, with a ceilingNew chat, for image generation and its ceiling together. A server-side route with my provider key in the project’s environment and never in anything the browser downloads. It takes a prompt, a size and a style, requires a signed-in user and returns 401 otherwise, and before calling the model it writes to the generations log and checks two limits I can configure (per account over a rolling window, and a workspace total) returning a clear limit message rather than an error. Compute the limit and the cost estimate on the server. Accept neither from the client. When the model responds, handle both base64 in the body and a URL, write the bytes into my own storage under the workspace, and insert an asset row with the prompt. What I am asking you not to do is call the provider from the browser or store its URL. The key would be readable and the link expires. Then wire the generate panel from step 01 to the route, and show me the limit refusing an eleventh call with the limit set to ten.
Say "not from the browser" and then check the diff for it. Calling an API directly from a component is the natural thing to write when the interface came first, and here it does not merely leak a key. It publishes a key somebody else can spend.
- 04
The library made real, uploads, and the edit route
The grid you already looked at, now over real assets, plus your own photographs and a second generation path. Fast, because the screens exist.
PromptBuild the library and the editorMake the library real: the grid reading assets with working filters by type and source, the prompt shown on each generated asset, the detail panel, and delete. Add uploading my own files into the same storage and the same table, differing from a generation only by the source field. Then an edit route taking an existing asset and a description of a change, calling the image model in edit mode, and saving the result as a new asset recording the original it derived from and the instruction given (the original is never overwritten) going through the same log and ceiling as step 03. Add a crop tool and simple adjustments handled locally with no model call, and make an uploaded video preview properly rather than showing a broken thumbnail. Then show me an edit whose original survives.
Give this its own pull request rather than stacking it on the generation chat. Of the changes in this build it is the one most likely to need restoring, and you do not want the working generation route travelling backwards with it.
- 05
Captions and the brand kit, in a separate chat
The writing half. Its own chat because it is the part you will iterate on most, and its own diff because three variants versus one string is a decision worth reading.
PromptAdd captions, hashtags and the brand kitNew chat. Make the brand kit page real first: colours, a logo upload into storage, and a paragraph describing the voice, stored per workspace. Then caption generation as a server-side route taking a post and its selected assets, sending my brand voice paragraph verbatim with the title, and returning three distinct variants stored as rows against the post with one marked primary, not one string replaced on each call. Then hashtag suggestions from the caption I kept rather than the title. Both go through the same log and ceiling as the image routes. In the interface show the three variants together with my choice marked, and let me edit any by hand. Nothing I have typed gets rewritten unless I ask.
Check the diff for whether the variants are rows or one delimited string. The string version works perfectly on the day it ships and silently discards your alternatives, which defeats the only reason for asking for three.
- 06Destination
The previews finished, the export, then merge and post something
The frames made accurate, a real file at the end, the spend figure checked against the provider, and only then the merge that publishes it.
PromptBuild the previews, the export, and rehearseLast chat. Finish the post builder and the previews: the caption and hashtags from the previous chat, the aspect ratio and feed type stored on the post, and each of the five frames exactly right rather than approximately: the real aspect ratios, the caption truncation each network applies, and a visible warning when my image does not match the selected platform’s ratio. Add a per-platform download of the rendered post as an image file, and a dashboard with recent assets, recent posts and this period’s generation count and estimated spend. Then check the cost arithmetic in the generations log against my provider’s published prices and tell me where it could drift. Finally, before I merge, make one real post with me: generate, edit once, three captions, pick one, hashtags, preview on the two networks I use, download, and compare the dashboard spend with my provider’s own usage page.
Do that comparison before the merge, not after. A merge into the branch your Vercel project deploys from is the moment the generation route becomes reachable by anybody you have given an account to, and the ceiling and the cost figure should both have been checked by then.
Protecting Data, Workspaces, and API Costs
Beyond basic data security, AI applications must protect your budget. Learn how to isolate tenant workspaces, secure user files, and enforce strict API spending limits.
Outsource authentication to dedicated services
Sign-up, sign-in, sessions and password resets belong to whatever auth service ships with your database. A hand-rolled one that is wrong is wrong silently. Nothing about this application argues for anything exotic.
Require user login for all AI generation calls
Worth naming as the pattern to copy, because the template does it correctly: all four AI functions check for a valid session and refuse with a 401 otherwise. An open generation endpoint is an invoice rather than a data leak. Somebody finds it, loops it, and you pay for every call. Check this first on anything you add, and check it again on the day you add a new one.
Separate login access from budget spending caps
The other half, and the one the template leaves to you. Signing in identifies whose enthusiasm is spending the money. It does not cap it. You want a record of every call including the image ones, a quota per person over a window, and a hard total that stops the feature rather than warning you. Treat an unmetered paid endpoint as a security problem and not a billing one, because that is how it will behave.
Isolate all data strictly by workspace
A workspace goes on every row and every access rule reduces to "does this row belong to the workspace the person asking belongs to". One function answers that question and every rule leans on it, which makes that function and the column it reads the most load-bearing lines in the project.
Validate permissions on every data change
The rule to take away from this section. An update rule normally answers "may I edit this row?". It also has to answer "what may this row become?", and leaving the second half out lets somebody edit a row they legitimately own into something they should not reach. That matters most on the record saying which workspace a person belongs to, because it is the answer every other rule depends on. Pin it explicitly, and check it on the way in as well as out.
Enforce workspace boundaries on file storage
The other rule worth carrying away, and on this application it bites hardest on files. It is easy to write a storage rule called "users can delete their own workspace’s assets" whose condition only asks whether somebody is signed in. The name reads correctly, every test passes, and the restriction does not exist, so any signed-in user can delete any workspace’s library. Read your storage rules with the names covered up, and check each condition against what it is supposed to prevent.
Restrict public URLs to published assets
Unlike an accounting export or a task attachment, a social image is something you intend to publish, so a world-readable URL for it costs you very little and saves real complexity. This template takes that trade for both its buckets and it is defensible. Two things to hold alongside it: the library also holds drafts and uploads you may never post, and "public" means anybody with the URL, forever. If either matters to you, serve them through short-lived signed links instead.
Lock down delete permissions
A read you did not intend is bad. A delete you did not intend is worse, because there is no version of it you can undo from the application. So of all the access rules here, the ones on delete deserve reading twice, and the honest way to check them is to sign in as a second workspace and try to remove the first one’s work.
Treat the prompt log as a stored record
Keeping the prompt beside the asset is genuinely the best feature in a library like this. It is also a stored history of what people typed, which occasionally includes things they would not have typed into a shared field. Decide who can read the log, keep it inside the workspace boundary like everything else, and be aware that it is exactly the kind of table nobody thinks to protect because it feels like metadata.
Keep API keys strictly on the server
The provider key belongs on the server and nowhere else. In the app your team downloads it is a key anybody can extract and spend. Then the question people skip: your brand kit, your caption drafts and whatever a user typed all leave your database when you make a request. Decide what is allowed to go, write it down, and check your provider’s terms on what it does with what you send.
Enable automated backups to protect AI assets
No backup is taken of your library, your brand kit or a single post. Daily backups, kept for a week, start on Supabase Pro at $25/mo. Worth doing here for a reason specific to this application: your assets cost money to produce, so losing them is not an inconvenience, it is a bill you pay twice.
Review the access rules (row-level security policies) on every table. For each one, tell me in simple terms who can view, add, edit, and delete records, confirm that people can only reach their own data while the right roles can reach more, and flag anything left open that shouldn’t be.
Paste this into the chat before launch so v0 checks nobody can see data they shouldn’t.
One rule outranks the rest here: the database service key and the model provider key belong on the server only: never in the app your team downloads, and never in a repository. Either one that gets out is burned, and the provider key is the one somebody will actually spend: replace it the same day and check your usage dashboard for what was done with it.
What speeds the build, and what slows it
Speeds the build
- One screen per message, checked in the live preview before you ask for the next one
- Adding a database as soon as a screen needs to remember something, so v0 wires it up as it builds
- Clicking the thing you want changed in Design mode, rather than describing where it sits
- One feature per chat, so its history reads as a straight line you can walk back
- Sending a finished chat over to GitHub before starting the next feature, rather than stacking several together
Slows the build
- Asking for the whole app in one message instead of one screen at a time
- Building screens for data the database does not hold yet
- Describing which button to change when you could just click it
- Letting one chat run for weeks, so going back to an older version undoes everything built after it
- Approving several messages in a row without looking at the preview after each one
Connecting GitHub (Optional)
Every change in v0 is saved automatically without any technical setup. You only need to link GitHub if you want a private copy under your own control or plan to hand the codebase over to external developers.
Every message is a version
Each time a message changes your code, v0 saves it as a new version. Restoring an older one adds it back as the newest version instead of branching, so the history stays one straight line.
Versions, v0 docsUndo from the chat itself
Scroll back through the conversation and click the revert arrow on any earlier reply, or open the version number in the top right to jump straight to a specific one.
Connecting GitHub creates a real repository
From the chat’s Git panel, connect an existing repository or create one. v0 never writes straight to your main branch: every code-changing message is committed to its own working branch first.
GitHub integration, v0 docsA pull request is how it gets merged
When you’re ready, publish and open a pull request from that working branch into your base branch, review it like any other, and merge it. Starting a new chat picks up a fresh branch for the next round of changes.
This can also be v0’s deploy path
If the branch your pull requests merge into is also the linked Vercel project’s production branch, merging one triggers a production deployment. If it isn’t, the merge just follows whatever branch behavior that Vercel project is already configured with.
GitHub integration, v0 docsWhere to host your application
Hosting gives your app a home on the internet so anyone can open it via a web link. Choose a service below to make your site live. (Your database, logins, and business records are stored separately in Supabase, covered below).
| Host | Best for | Notes | Free tier |
|---|---|---|---|
| Vercel | One-click deploys | Connect the repository and each push publishes itself, with nothing for a Vite project to configure. Settle which plan you belong on first: Hobby is licensed for personal, non-commercial use, and content you post for a business is commercial, so Pro, at $20/user/mo. | Pro from $20/user/mo (Hobby is non-commercial) |
| Netlify | Drag-and-drop or Git | Connect the repository, or drop the built folder onto the page and be live in a minute. Add the redirect rule it asks for, or a link straight to one asset in your library answers with a not-found page. | Free tier |
| Cloudflare Pages | Image-heavy pages | The app is served from wherever the person opening it is, which suits a library of pictures better than most apps in this catalogue. Worth a look if you will browse hundreds of assets from more than one country. | Generous free tier |
| GitHub Pages | Not really this app | Free publishing from a GitHub project after one routing setting. Listed to be ruled out: free means a public repository, and this one sits beside a database and a set of functions that hold a key somebody can spend. | Free from a public repo only |
| Firebase Hosting | Teams already on Google | One round of setup, then a single command per release. No argument for it comes from the app. The argument is that your other accounts are Google already. | Free Spark tier |
| AWS Amplify Hosting | Teams already on AWS | Publishes out of the AWS console, and needs the same rewrite rule for a deep link to resolve. Chosen when AWS is on the invoice already. | Free tier (build + hosting) |
| Surge | Publish from the terminal | One command puts the built folder online, no repository involved. Fine for showing somebody the generator. Wrong for anything holding a key. | Free - unlimited publishing |
| DigitalOcean App Platform | DigitalOcean users | Builds and serves inside the account you already have. One fewer supplier and invoice, which in a small company is a real argument. | Free - 3 static sites, 1 GB/mo transfer |
All eight serve the app well enough that speed is not the deciding question. Three others are: whether the plan permits commercial use, since Vercel’s Hobby tier does not. Whether it publishes from a private repository, given the key sitting next to this code. And whether a deep link resolves for a browser that has never seen your site, because a link to one asset is what you will paste to somebody asking which picture you meant.
One thing to check on the day you go live, and it is not the hosting. Confirm your spending ceiling is enforced on the deployed functions and not only in your local copy, because a limit that exists in development is a limit that does not exist.
Keep your data in Supabase
Your assets, posts, copy variants and brand kit, the generated files themselves, and the functions that call the model, which is where the provider key belongs and the only place it should ever be.
| Service | Best for | Notes | Free tier |
|---|---|---|---|
| Supabase | Data, auth, files, model calls | The library and the posts sit in Postgres, accounts come from its auth service, the generated images go into its storage, and its edge functions make the model calls, which matters more here than on any other template, because those functions are the only place the provider key and the spending ceiling can both live. Setting up is opening a free project and handing the app the project URL and the publishable key. The provider key goes into the function secrets afterwards and nowhere near the browser. The line to watch as you grow is file storage rather than the database. | Free tier, then usage-based |
Where AI genuinely helps a content studio
Ready-to-use prompts to expand your studio’s backend. The first prompt sets up mandatory spending guardrails and API logging, while the following prompts add high-value AI features like multi-format asset generation.
Log every generation and put a ceiling on it
The template records copy requests and does not record image ones, which means the expensive calls are the ones with no history. Fix that before you add anything else, because everything below spends money too.
Add a generations table that records every model call (who made it, which workspace, which model, the prompt, the size and quality asked for, whether it succeeded, and a cost estimate) and write to it from all four AI functions, images included. Then add a ceiling: a limit per person per rolling window and a workspace total, both settings I can change, checked inside each function before it calls the provider and returning a clear "you have reached your limit for today" rather than an error. Add a small usage panel showing calls and estimated spend for the current period, by person. Do not let the client send the limit or the cost. Both are read on the server.
Turn one good image into a set that matches
The thing you actually want after a generation you like is four more like it, in the other aspect ratios, with the same subject. That is a loop over the same call plus the prompt you already stored.
Add a "make a set from this" action on an asset. Take the stored prompt, generate the same subject at each aspect ratio I have platforms for, and show them as a group I accept or discard together, with the cost estimate for the whole set shown before I confirm. Reuse the ceiling from the generations table so a set counts as its number of images and not as one. Keep the group linked to the original asset so the library shows them together rather than as five unrelated pictures.
Draft the caption from the picture, not from the title
A caption written from a post title is a caption about a title. One written from the image itself notices what is actually in the frame, which is the difference between filler and something worth reading.
When drafting a caption, send the selected image to the model alongside my brand kit and any title I have written, and ask for three variants that refer to what is actually in the picture. Keep all three against the post and mark the one I choose. Send the brand voice paragraph verbatim and nothing else about my other posts. Where the image is ambiguous, have it say so in a short note beside the variants rather than inventing a detail. A caption confidently describing something that is not in the photograph is the failure worth designing against.
Check the post against the platform before you export
Every network has limits you will forget: caption length, hashtag counts, aspect ratios, text-in-image rules. Most of that is arithmetic, and the part that is not is worth a sentence of judgement.
Add a pre-export check on a post. Compute what you can (caption length against each platform’s limit, hashtag count, whether the image matches the aspect ratio for the chosen feed type) and show those as plain pass or fail with the actual numbers. Then send only the caption and the platform to my ai function for one line on anything that reads badly for that audience. Never rewrite my caption automatically, never call the model for the arithmetic, and show which checks are computed and which are an opinion.
Ask your own library what has been working
After a few months the library knows things you do not: which prompts you keep reusing, which variants you always pick, what you generate and never post.
Add a panel that answers questions about my own library and posts. Compute the figures with queries (assets by type and month, generations that never made it into a post, which caption variant position I choose most often, the prompts I have reused) and use the model only to describe what the numbers suggest. Show the query and the counts under every answer, state the period, and where the sample is too small to mean anything, say so instead of finding a pattern in nine posts.
v0 doesn’t ship its own model for these prompts, so you bring an API key for whichever provider you want, and v0 writes the route that calls it. Start with a cheap model while you’re still iterating on the prompt itself, then swap in a stronger one for the version that ships, and keep every AI feature behind that one route so there’s only one key to rotate.
Get a head start with our template
All three routes above start at an empty folder, which is not the only available starting line. This studio already generates, already files what it makes, and already previews five networks, so the weeks the library, the brand kit and the previews would have taken become an afternoon of adding your own key and your own colours.
AI Content Studio
The exact content studio this guide builds, packaged so you can open it, point it at your own backend, and make it yours from there. Generate images with AI, write the captions to go with them, and build posts for every social network. A brand kit keeps everything on-brand, and a library keeps all your assets in one place.
The key benefits of starting with a template
Everything you need to ship a custom AI content studio: dual generation workflows, a unified asset library, brand kit integration, multi-platform previews, and multi-tenant security.
Building the core from scratch
~89 hrs
Opening the template, already built
~1 hr
~88 hrs of building you skip
Two deliberately different measurements. The build is the ~89 hrs. The hour is what adoption costs: a database of your own, a provider key, your brand kit, and one generated asset to prove it works. Writing the paragraph that describes your brand voice costs the same on either path, so neither figure includes it.
Dual AI image workflows
Generate new images from text prompts or edit existing assets with AI. All outputs are automatically downloaded into your own secure cloud storage, preventing broken or expiring links.
Generate 3 caption variants per post
Copy generation returns three options written from your brand kit, all three stored against the post with the one you chose marked as primary, so you are picking rather than accepting, and the alternatives are still there next month. Hashtag suggestions run off the caption you actually kept.
Unified asset library with prompts
Uploads sit beside generated and AI-edited assets as equals, each with its type, its size, and the prompt that produced it. There is a crop tool and an image editor over it, and video assets can be uploaded and previewed. Generation itself is images only, and the copy never suggests otherwise.
Brand kit wired into every caption
Your colours, your logo and the voice you want the model to write in, stored once and sent with every caption request. This is the field that decides whether the output is yours or merely competent, and having it already plumbed through is most of what the template saves you on quality.
5 social platform previews & PNG export
Preview exact aspect ratios and feed layouts for Instagram, X, Facebook, LinkedIn, and TikTok. Export ready-to-publish PNG files tailored for each network. (Note: Direct auto-posting is not included).
Workspace isolation & 37 built-in security rules
Complete multi-tenant data protection. Automated database policies ensure users access only their workspace assets, while server-side key management prevents API credential leaks.
From founders who build on our templates
We needed to get a working product in front of users fast. Starting from this template instead of a blank repo let us customize everything in our AI tools and launch straight to production without building basic infrastructure from scratch.
Jeevan ThomasFounder & CEO, Hado.aiCommon questions
No, and this is the first thing to know before comparing it with anything. No connection to any network exists in it: no login to a platform, no scheduling, no queue. What it does is build the post and show you exactly how it will look on Instagram, X, Facebook, LinkedIn and TikTok, then let you download it as an image per platform so you can post it yourself. Adding real publishing is a substantial addition rather than a small one: each network needs its own authorisation, its own API and its own retry handling, which is genuinely most of what the scheduling tools charge for.
No. A date has nowhere to go. The posts table has no scheduled time and nothing runs on a timer. It is a place to make the content, not a calendar to release it from. If you want scheduling, the honest advice is to decide whether you want this app plus a scheduler you already pay for, or a build that does both, because the second one is the bigger half of the work.
Whatever your model provider charges, and that is the answer you should get from them rather than from us, because it moves. Two things worth knowing before you look: image generation is usually priced by size and quality rather than a flat rate per picture, and providers increasingly bill images by tokens, which means a per-image figure is an estimate rather than a price. Text is cheap by comparison. Read your provider’s own pricing page, generate a handful with the settings you plan to use, and check the usage dashboard. That measurement is worth more than any figure quoted elsewhere.
As it stands, yes, and it is the first thing to add. The four AI functions are properly locked to signed-in users and they handle the provider saying "slow down" or "out of credit" gracefully, so a stranger cannot spend your money. What is missing is any cap on somebody who is signed in: no quota, no rate limit, and no log of image generations at all, only of copy. The first AI prompt in the section above adds the log and the ceiling together, and on this application that is not an optional extra.
One model for images and one for text, and both are environment settings rather than values buried in the code, so switching is a configuration change. That matters more here than it sounds: image models are being replaced quickly, and the one this template defaults to is already listed by its provider for retirement during 2026, with a named successor. Check your provider’s own deprecations page rather than trusting a date from a guide, and treat the ability to swap as a feature you want to keep working.
Yes, and they sit in the library as equals rather than in a separate place: same filters, same use in a post, same crop and edit tools. That combination is worth more than it sounds: most real content is a mix, and a tool that treats your own photographs as second-class is one you stop opening. Video files can be uploaded and previewed too. Generation itself is images only. Nothing in it generates video.
No. It handles video as an asset (you can upload one, keep it in the library and preview it) but no video generation exists anywhere in it, and no editing beyond the preview. If video is the point for you, that is a different build with different costs: generated video is priced far above images at every provider, which makes the spending ceiling the first thing to design rather than the last.
That is between you and your model provider, and it is worth ten minutes of reading their terms before you put a generated image in a paid advertisement. Most commercial terms are permissive about output, and the details differ by provider and change over time. What the template does to help is keep the prompt beside every asset, which means you can always answer where a picture came from, a question that gets asked at exactly the moment it is inconvenient.
Several people, yes. Everything hangs off a shared workspace and access rules are written around it. Different permissions, no: this template has no roles at all, so everyone in the workspace can do everything, including generating. That last part is why the spending ceiling matters more than a role system would: an approver who cannot stop somebody generating is not much of a control. Adding roles is a described change rather than a setting.
Three lines. Somewhere to hold the data and somewhere to serve the app, both with free tiers, and the model provider, which is the one that moves with use and has no ceiling until you build one. Once you are generating for real, the upgrade worth making is Supabase Pro from $25/mo, and here it is genuinely for the storage rather than the pause: generated images accumulate faster than anything else in this catalogue and a few hundred will pass the free tier’s 1 GB.
Nothing here is proprietary. The library, posts, copy variants and brand kit sit in plain PostgreSQL tables any Postgres host accepts from a standard dump, and the assets are ordinary image files you can copy. That is worth more on this template than most: the assets cost money to produce, so being able to walk away with them is the difference between owning a library and renting one.
Yes, and every host listed above attaches one in a few clicks with HTTPS included. Do it before you start sharing links to individual assets, because those URLs are how you will show somebody which picture you meant, and links shared before you move are links that break afterwards.
No. You describe the screen you want in the chat and v0 generates the React and Next.js code behind it. Sign up, pick a plan, and connect a database once your screens need real data. The setup section above walks through each one.
Both, but not automatically at the same time. v0 generates the interface first. The backend (a database and the API routes that use it) is something you ask for once a screen actually needs to save or load real data.
Free plan credits reset monthly, and the 7-messages-a-day cap resets every day. If you hit either limit mid-build, what you’ve already built stays put. You wait for the reset or move up to Plus to keep going right away.
References
Sources checked August 2026- 01Pricing (AI credit allowances, what one credit generates, plan limits), Later. later.com
- 02Pricing (credit tiers stated as generation counts, credits per image), Predis.ai. predis.ai
- 03Pricing (per-channel tiers, free-plan limits), Buffer. buffer.com
- 04Pricing (credit counts without a stated unit, tier limits), Ocoya. ocoya.com
- 05Pricing (per-seat entry tier and the jump to workflow credits), Copy.ai. copy.ai
- 06API pricing (image and text model token prices; per-image figures are calculator estimates), OpenAI. developers.openai.com
- 07Model deprecations (image model retirement and its replacement), OpenAI. developers.openai.com
- 08Pricing (Pro plan, free-tier storage and egress, project pausing), Supabase. supabase.com
- 09Web developer hourly rates 2026 (freelance and agency benchmarks). developex.com
- 10Row Level Security, Supabase docs. supabase.com
- 11Storage access control, Supabase docs. supabase.com
- 12Edge Functions secrets and environment variables, Supabase docs. supabase.com
- 13v0 homepage. v0.app
- 14Pricing (Plus, Business), v0. v0.app
- 15Pricing details (Free tier, credit rollover), v0 docs. v0.app
- 16Databases (connecting Supabase and others), v0 docs. v0.app
- 17Full-stack apps, v0 docs. v0.app
- 18GitHub integration, v0 docs. v0.app
- 19Deployments, v0 docs. v0.app
- 20Design mode, v0 docs. v0.app
- 21Versions, v0 docs. v0.app
- 22Pricing (Hobby plan), Vercel. vercel.com
This guide is general information, not legal advice. What you may do commercially with what a model generates, and what a provider may do with what you send it, are set by that provider’s terms and by your own local rules, so read both before a generated image goes into paid advertising. Third-party prices, plan terms, and market rates are quoted from the sources above and were last checked on the date shown. Vendors change them without notice, and model prices and model availability move faster than anything else here, so confirm before you budget. Build hours and the cost estimates derived from them are our own estimates, not quotes. v0 is a product of Vercel. Verify current capabilities and pricing before relying on them.