Large Language ModelsGenerate imagesGenerate videos
Create an AI Image Generator Website: Template and GitHub Project
A working template for an AI image generator website: the Next.js stack, the GitHub project layout, the server route that calls an image model API, the prompt page, safety checks, rate limits and deployment. Every file is shown, so you can copy it and ship.
Most tutorials on how to create an AI image generator website end with a screenshot and a vague promise. This one ends with a working project: a prompt box, a server route that calls an image model, a polling loop, a result view and a deploy checklist. Every file fits on this page, so you can paste it into a fresh repository, push it to GitHub and have a live generator the same afternoon.
The template is small on purpose. It has four files of real logic, no database, no login provider and no state library. That makes it easy to read in one sitting and easy to extend later with accounts, history or video. If you can run npm install, you can ship it.
💡 Quick answer: an image generator website is a form, one server route that hides your API token, a polling loop and an <img> tag. Everything else is polish.
What the Template Does
The finished site takes a text prompt, sends it to an image model, waits for the result and shows the picture with a download link. The browser never sees your API token, because every call goes through your own server route.
Here is the full request flow:
The visitor types a prompt and presses the button.
The page posts the prompt to /api/generate on your server.
Your server validates it and creates a job on the image API.
The page asks /api/generate/{id} for the status every two seconds.
When the status turns to succeeded, the page shows the image URL.
Features at a glance
Feature
Included
Where it lives
Prompt form with character limit
Yes
components/Generator.tsx
Server route that creates the job
Yes
app/api/generate/route.ts
Status route for polling
Yes
app/api/generate/[id]/route.ts
Loading, error and timeout states
Yes
components/Generator.tsx
Download link and local history
Yes
Added in the gallery step
Accounts, billing, user galleries
No
Add after the first launch
Who it fits: solo developers get a portfolio piece that actually generates pictures. Agencies get a base they can brand for a client in a day. Product teams get a prototype to test demand before they invest in a full platform.
Stack and Project Layout
Choose the stack
The template uses Next.js with the App Router, TypeScript and Tailwind CSS. One framework gives you the page and the server routes in the same repository, which is why it suits a first project. Any stack with a server works the same way: React with Express, SvelteKit, Nuxt or plain Node.
Create the project and put it on GitHub in four commands:
The backend is a text to image API. The PicassoIA API follows the Replicate convention: POST /v1/models/{owner}/{name}/predictions creates a job, and GET /v1/predictions/{id} returns its status. At the time of writing, the API serves four models: picassoia/picassoia-image, picassoia/picassoia-image-editor-pro, picassoia/picassoia-video and picassoia/seedance-2.5-lite. Create your token on the PicassoIA API page.
Copy the file to .env.local and paste your real token there. create-next-app ignores every .env* file, so add the line !.env.example to .gitignore if you want the example file in the repository. Never put the token in a variable that starts with NEXT_PUBLIC_, because Next.js ships those to the browser.
The body follows the Replicate convention, an input object that holds the prompt. Each model page lists extra fields, such as aspect ratio, that you can add next to prompt. The 4,000 character check matches the documented prompt limit, so users get a clean error before the request leaves your server.
Poll until it finishes
Generation is asynchronous. The first call returns an id, and you ask for the status until it says succeeded or failed.
The id check matters. Without it, a visitor could pass ../ segments and make your server call a different endpoint with your token attached.
Handle errors and limits
Three failure types show up in real traffic:
Bad input: return 400 before you spend a request.
Upstream errors or busy queues: return 502 or 429 and let the page show a retry message.
Slow jobs: stop polling after about two minutes and tell the user.
The API allows 5 concurrent predictions per account, shared across every token. If your site gets ten visitors at once, five wait. Add a small queue or disable the button while a job runs.
Import it in app/page.tsx and render <Generator />. Run npm run dev, open localhost:3000, type a prompt and you have a working generator.
Gallery and downloads
Add two touches once the basics work. Wrap the image in a link with the download attribute so users can save the file. Then store each result in localStorage, an array of { prompt, url } objects, and render it below the form as a grid. That gives you history without a database.
💡 Keep the prompt as the alt text. It helps screen readers, and it gives your gallery useful text for search engines.
How to Use Imagen 4 on PicassoIA
Before you hard-code a look into your site, test it where iteration is cheap. The PicassoIA website has a playground for every model, and the controls follow the same pattern: a prompt field, a few settings and a generate button.
Paste a structured prompt: subject, setting, light, lens and texture.
Choose a 16:9 aspect ratio if the model offers it.
Press generate and check the result at full size.
Change one detail at a time and generate again.
A prompt that works well for photographic output:
A ceramic cup of black coffee on a worn oak table, window light from the left, 50mm lens at f/2, shallow depth of field, visible wood grain and steam, Kodak Portra 400 colors.
Each part of that prompt does a job:
Part
Example
Why it helps
Subject
A ceramic cup of black coffee
Names the one thing the picture is about
Setting
A worn oak table
Gives the background a material and a mood
Light
Window light from the left
Sets shadows and direction
Lens
50mm at f/2
Controls depth of field and perspective
Texture
Wood grain, steam
Pushes the result toward a real photograph
Compare three models
Run the same prompt through several models before you decide what powers the site. The API serves only the four picassoia/* models at the time of writing, so the others in this table are for choosing a look in the playground.
Keep the winning prompt as your starter text in the placeholder attribute, and turn your best three prompts into clickable example chips under the textarea. Visitors who see a good example write better prompts, and better prompts mean fewer wasted generations.
Add LLMs and Video Later
Draft code with an LLM
You can build the whole template above with a coding assistant. Claude Sonnet 5 and GPT 5.6 Sol are both listed for coding tasks, and Gemini 3.5 Flash suits quick edits. Paste in this article's folder tree and ask for one file at a time, then read every line before you commit it.
Rewrite short prompts
Most visitors type five words. A language model can expand them before the image call:
Add a rewrite step in route.ts that sends the user's text to a model such as Kimi K2.6.
Instruct it to return one prompt with subject, light, lens and texture.
Send that prompt to the image model and show both versions to the user.
Animate the results
The same two routes handle video. Change PICASSOIA_MODEL to a video model, such as picassoia/seedance-2.5-lite, and the output becomes an MP4 link. Render it with a <video controls> tag and raise the polling interval, because video takes longer than images. To compare options first, the Seedance 2.5 Lite page and the Wan 3 page show what each model produces.
Ship Without Surprises
Moderate prompts
A public generator gets abused within days. Run each prompt through a moderation model before you create the prediction. Llama Guard 4 12B is built for that job: it labels a prompt as safe or unsafe, and you block the request when it says unsafe. Add a visible terms notice under the form too.
Rate limits and queues
Risk
Fix
One visitor floods the route
Limit requests per IP, for example 10 per hour
More visitors than concurrent slots
Disable the button while a job runs and show a wait message
Token leaks in the browser
Keep calls on the server and never use NEXT_PUBLIC_ for secrets
Runaway cost
Cap daily generations and alert when you reach 80%
An in-memory counter works on a single server. On serverless hosting, every function instance has its own memory, so use a shared store for the limiter.
Deploy and monitor
Deploying takes five steps:
Push the repository to GitHub.
Import it into your hosting platform of choice.
Add PICASSOIA_API_TOKEN and PICASSOIA_MODEL as environment variables.
Set a maximum function duration long enough for your polling route.
Open the live URL and generate three test images.
After launch, log the status of each job (never the token) and check the failure rate weekly. A sudden rise usually means a model change or a limit you hit. Write a short README.md too, with the two variables, the run command and a screenshot, because the README is the first thing people see on a GitHub project.
Build Yours on Picasso IA
You now have the pieces: a stack, a folder tree, two server routes, a prompt page and a safety checklist. The fastest way to make the site feel finished is to pick its look before you write more code.
Open Picasso IA, run your first prompt through Imagen 4 or FLUX 2 Pro, and save the three results you like most. Those prompts become your example chips, your landing page and your first test cases. Then create your API token on the PicassoIA API page, paste the code from this article into a new repository and press generate. The first image on your own domain is the moment the project becomes real, so make that prompt a good one.