How a client questionnaire turned into a separate application with saved drafts, a private dashboard and branded email.
Hi there, I'm Alex, a Shopify specialist based in West Sussex, UK.
Before work can start on a Shopify store, there's a lot of information to gather, which helps build a great store for the client. An efficient way to collect these details is through an onboarding form, which is simply a questionnaire that collects everything needed in one place.
This blog post is about the one I built for Digi Creative. It began as a simple form on my own website, and grew into a separate application.
If you run a service business like mine, or you're just curious what you can now put together with AI, you should find this article interesting.
Outlining the requirement
Before the form existed, I gathered everything the way most freelancers do. A few emails back and forth, a couple of WhatsApp messages, a phone call, and the odd detail scribbled down halfway through a build. Every project was slightly different, so I'd ask for whatever came to mind at the time and fill the gaps later.
There's more to cover than you'd think. Who they are, what they're selling, how many products the site will have, whether they own the domain, who handles their email, what the site should feel like, and what happens when somebody wants to send something back.
Spread across many channels, the information is hard to keep together and easily lost in the whirlwind of files on your computer. Answers arrive in dribs and drabs, so by the third week you're spending most of your time chasing what you need rather than building. It was quietly holding up my own work more than anything else in the process.
There's a second reason, and it's one I've learned the hard way. I've recently had two projects stall. Terms are difficult to set out properly on a call or in an email — it can feel awkward, and it rarely ends up written down anywhere. Setting out a clear timeframe matters, and it can be done without damaging the relationship.
So I set out to build a guided form. Something a client could work through in manageable stages, that asked the time-consuming questions for me. The end of the form also sets out my terms clearly, so nobody is caught out later.
How the form was first build
The first version was designed and built through Claude chat, in plain HTML, CSS and vanilla JavaScript. I made two copies of it: a standalone HTML file, and a Shopify Liquid version I could drop straight into my existing site.
I deliberately didn't convert it to React or Next.js. It needed to load quickly and be easy for me to edit six months later. A framework would have added a build step and a set of habits I didn't need.
What it contains is a welcome screen, eleven sections, and a review page at the end:
- About you
- Your business
- Your domain
- Products & collections
- Pages & content
- Brand & images
- Shipping & returns
- Style
- Customer persona
- Final details
- Review and send
Along the way there are conditional questions, which let the form handle multiple cases — whether a client already owns a domain or not. Once the form has been submitted there's a confetti pop. It's a long form, and it just adds a bit of pleasant atmosphere at the end.
The customer persona section is optional on purpose, as it can take some time to complete. Established businesses usually fill it in from memory. Newer ones often stop at that point and realise they've never actually written down who they're selling to. Which is a useful thing to discover before I start designing for them.

Putting it on the Shopify site
The Liquid version uses Shopify's own form mechanism to email the completed answers to me. That makes it a mostly straightforward and quick setup. It's still important to test it, to make sure the email really does come through.
I kept the standalone HTML copy as well. It later became the foundation for everything that follows.
What version one genuinely got right
- The ground work to the forms design and usability
- Clients could work through a long questionnaire one section at a time instead of facing a wall of fields.
- The browser saves progress to a persons local storage
- Conditional fields and repeated validation meant far fewer half-answered questions.
Why I built a separate system anyway
The first working version was fine, with just a few aspects missing — not essential, but very useful. Did it warrant a separate system for the amount it gets used? Probably not. I built it anyway.
Limitations of first version
Email-only submissions. Once a form is completed it's emailed to me, and the client has the option to copy their answers. Those emails could easily be lost or deleted, with no backup.
Browser drafts are tied to one device. If a client started the form on a laptop at work and wanted to finish it on the sofa with their phone, the progress does not sync. Everything is saved in that specific browser with no backend behind it, so if they clear their browser data all progress is gone.
No admin panel. A submission arriving through the Shopify email system wasn't easy to work with. It had to be turned into a readable document and then stored somewhere. A dashboard gives me every form in one place, in a clear format, with the option to add private notes.
The architecture I settled on
Here's the architecture behind the finished form. To the client it looks like exactly the same form with a couple of added benefits, when in fact there's a fair amount going on behind the scenes. Here's what each part is responsible for.
| Service | What it's responsible for |
|---|---|
| Cloudflare Pages | Serving the public form and the admin pages to the browser. |
| Supabase | The PostgreSQL database, admin side, Row Level Security, and the server-side Edge Functions. |
| Resend | The three transactional emails: draft link, client confirmation, admin notification. |
| Cloudflare Turnstile | An anti-spam challenge in the browser, checked again on the server. |
| GitHub |
Version control, and the source Cloudflare Pages deploys from. |

How draft saving actually works
A draft can be saved as soon as the client has entered their email on the first stage, which means they never need to create an account. When a section is finished, the browser validates it before making any request at all. The save-onboarding-draft function then checks it again on the server, confirms the request came from the domain, checks the Turnstile token to create a draft that expires after 90 days of inactivity. An email goes out on the first save, which includes a private return link to access their open form.
As a backup, the form still saves progress in the browser while they're completing each section.
The Dashboard
With a separate system comes a very useful dashboard for managing every form entry. The dashboard lists drafts and completed submissions together, with summary counts, status and more. Each submitted form is laid out in the same sections for easy reading.
I originally intended to have a couple of simple statuses, draft and submitted. ChatGPT went ahead and added: Reviewing, Information Needed, In Progress, Complete and Archived, plus private notes.
The private notes should be useful, although the other options are not needed right now. It just goes to show, AI will always try and extend something if it thinks it can.
Lastly there's also the option to save as a PDF, which I'll use to hand over to AI tools to assist with building the website.

The security decisions worth explaining
Most of the security decisions are handled by the AI, to make sure you're properly protected. Your job is to follow its instructions carefully and put sensitive information in the right place, so it never ends up publicly accessible.
A few of the security features in this form:
- Public visitors can't read, update or delete submissions or drafts.
- Access keys never appear in browser code or in the repository.
- The Edge Functions re-check required fields such as email format.
- Every final submission carries a unique idempotency key, so an impatient double-click can't create two records.
- If the database save succeeds but the email fails, the submission is still saved. The error is recorded for me, and the client isn't told their form failed when it didn't.
Improving the email design
Resend handles all the emails. Originally they were all plain HTML text. I wanted something more on brand, so I set about redesigning them. I told ChatGPT what I wanted and got there after a few tries.
Top tip: Ask for a preview, otherwise it will overwrite the existing design on file straight away. I updated the design several times, and fixed a recolouring problem where the text changed in dark mode on apple devices.
When I re-uploaded the files to update the email layout, nothing changed. After a few attempts, renaming the file, it finally updated — to my relief.
I really like having an email go out to the client and one to me. My notification carries a summary of the key details, which I can then click into to see the full form. 
Deployment and domain
Getting it live comes down to three separate jobs, and it helps to keep them apart in your head. The database is set up in the Supabase dashboard using two migration files — plain SQL files that build the tables and security rules, so the whole structure can be recreated from scratch if it ever needs to be. You run them in the SQL editor, then create an admin user and map it to the admin table.
Edge Functions are deployed from your machine
The Supabase CLI has to be installed on your desktop, which surprised me at first. Edge Functions aren't written in the dashboard — they're code sitting in your project folder, uploaded with a deploy command from your own machine.
The front end: GitHub to Cloudflare Pages
Push the project to GitHub, then connect that repository to Cloudflare Pages with these settings:
- Framework preset: none
- Build command: leave empty
- Build output directory: a single full stop
There's nothing to build, because it's plain HTML, CSS and JavaScript. From then on, every push to the main branch republishes the site automatically. Function updates still have to be deployed separately with the CLI.
The subdomain: leave your domain where it is
The onboarding site lives on a subdomain, and adding it changed nothing about the main site. This is the part worth reviewing carefully before you touch anything:
- Keep the domain registered and DNS-managed exactly where it already is.
- Add the subdomain as a CNAME pointing at the Cloudflare Pages address.
- Don't move your nameservers to a new provider. That affects everything else running on the domain, including your business email.
Done that way, the main Shopify site and your email carry on untouched, and the subdomain is the only thing that changes.

Could I have done this without ChatGPT?
No.
ChatGPT was instrumental. It produced a full twelve-page guide covering the whole setup process. I still asked plenty of clarifying questions along the way, because when you're building something client facing accuracy matters, and the extra time spent asking is less time spent troubleshooting later.
You only ever have part of the idea. The AI fills in the gaps that really matter — security rules, migrations, SQL configuration. Without that help, only a seasoned professional with years of experience could take on a build like this.
AI has really opened the doors to custom creations, and I can't wait to explore more of what it can do.
Key takeaways
- Start with the simplest version that's genuinely useful.
- Finalise form first before moving to a separate system
- Plain HTML, CSS and JavaScript were enough for all of it.
- Start on free tiers, but check each provider's current quotas.
Where it leaves Digi Creative
Clients now get one link, a form they can leave and come back to on any device, and a professional branded email. I now have a single place to review who's started, who's stalled and who's ready to build — with notes and statuses for effective management.
Want one of these for your business?
Are you after a custom onboarding form for your business, without the hassle of setting it up yourself? Get in touch and we can design and build it for you.
A guided, branded onboarding or enquiry form with saved drafts, a private dashboard and proper email behind it. It can work like my example, or be something completely different to match exactly what you need.
The same setup works for detailed quote requests, applications, a staff role or job database, or any long form you'd rather not chase by email.
Get in touch today and streamline your workflow.
Join the conversation