How to build a help center and support desk with Claude Code
Stop paying per agent and per answered question. Describe the library, the queue, and the four kinds of account in plain words, and Claude Code builds them for you: a search that finds the answer, live chat, and accounts that stay out of each other’s records.
Claude Code
$ Build a help center and support desk: articles and FAQs in categories with search over the body text, a contact form that suggests articles before it opens a ticket, tickets with attachments and a full timeline, live chat with an agent, and dashboards for customers, agents, editors, and admins.
- Library searchable
- Queue and chat wired up
- Ready for you to review
What a help center and support desk actually is
Two products sharing one database. A library your customers read without ever talking to you, and a queue for the questions the library did not answer, joined at the point where somebody gives up reading and starts typing.
The library half is the one with leverage in it. An article answers the same question for the hundredth person as cheaply as it did for the first, which is the only part of support that gets less expensive as you grow. The queue half is where your team actually spends its day, and where every hour costs the same as the last one.
That is also why nearly every reader arrives at this app already renting one. Support tools are priced against exactly those two halves: a monthly fee for each person working the queue and, across most of the market now, a second charge each time something gets answered. The bill is indexed to the two numbers you are trying to move.
What makes this genuinely hard to build is not the ticket list. It is that a help center only works if people find the answer, and finding is a search problem hiding behind an ordinary-looking page. Seventy-three per cent of customers try self-service somewhere in their journey, which means the article is usually the first thing your company says to somebody with a problem.
Search That Actually Finds the Answer
Search is the product here, not a widget in the header. A help center with fifty good articles and a search that matches on titles alone will send almost everybody to the contact form, and you will conclude you need more articles. Get search, categories, and related links right before you write article number fifty.
The Contact Form That Prevents Tickets Before They Start
The contact form is where the two halves meet. Suggesting likely articles while somebody types their question, before it becomes a ticket, is the single highest-leverage screen in the whole application, and it is usually the last one anybody builds.
Four Account Types, Each With Its Own Access
A customer, an agent working the queue, an editor writing the library, and an admin running all of it. Most applications have two kinds of user and get away with a flag on the account record. Four kinds, each of which may read some rows and not others, is where the access rules stop being an afterthought.
How often self-service actually works
14%
of customer service issues were fully resolved by the company’s own self-service channel, across the 5,728 customers in the survey Gartner published in August 2024. The most common reason it failed was not a hard question: 43% of the time, people simply could not find content relevant to their issue.
Gartner survey, published August 2024 (read on CX Today) · checked Gartner survey published August 2024
The parts every support desk is built from
Two of these six are systems wearing the costume of a page, and they are where the build time actually goes. The other four are where most of the visible work is.
Search That Looks Beyond Article Titles
Somebody types four words, half of them not the words you used in the article. Matching titles is not enough. You want the body text, the category, and ideally the questions people have asked before. This is the part worth over-building, because in the survey behind the figure above, the single most common reason self-service failed was that people could not find content relevant to their issue, and even for problems customers themselves described as very simple, only 36% resolved without contacting anybody.
Draft, Publish, Translate, and Retire Articles
A draft somebody is still writing, a published version customers read, a translation of it in another language, and eventually a version that is wrong and needs retiring. Model that from the start. Bolting a draft state onto a table of published articles later means every query in the application suddenly needs to remember which kind it is looking at.
Tickets With Their Full Conversation History
What a customer wants from their own ticket is the history: what they said, what your agent said back, when it changed hands, what got attached. Build the timeline as the primary thing and let the status be a property of it, rather than building a status field and discovering later that nobody can tell what happened.
Live Chat With Your Agents
This is the item people underestimate. A message has to arrive while both people are looking at the screen, which means subscriptions rather than page loads, and it brings its own questions: who is waiting, who picked this up, what an unread count means, and what the customer sees when every agent has gone home. Decide whether you are staffing a chat before you build one, because an unattended chat window is worse than no chat window.
Customer, Agent, Editor, and Admin Roles
Customers read and ask. Agents answer. Editors write the library, which is a genuinely different job from working a queue and usually a different person. Admins run users, settings, and the numbers. Four roles is the reason the access rules in this application multiply rather than add.
Analytics That Show Which Articles to Write Next
Which articles get read, which get marked unhelpful, and what people asked for anyway after reading them. That last one is the most valuable report in the whole application: it is a list of the articles you have not written yet, generated by your own customers.
Own the help center or pay per agent and per answer
Traditional support tools charge steep monthly fees for every team member you add, plus extra fees every time an AI answers a question, punishing your growth. Owning the help center is a single purchase, and neither of those numbers moves the bill.
Build your own
Own the help center outright: one purchase, the whole codebase, no seat count and no per-answer meter. Your fifth agent and your four-thousandth answered question cost exactly what the first did.
- Adding the fifth person to your support team costs nothing, so hiring is not also a software decision
- The same cost to run whether you answer forty questions a month or four thousand
- Your articles are pages on your own domain, indexed under your own name rather than a vendor’s subdomain
- Every question, article, and reply is in your own database, queryable without an export request
- What counts as resolved, how long a quiet ticket stays open, and which statuses exist are your decisions
- No surprise fees, subscription taxes, or per-answer charges when you add smart features to your app
Rent the help desk
Zendesk · Freshdesk · Intercom · Help ScoutWhat renting buys is a decade of accumulated support machinery. Routing rules, SLA timers, satisfaction surveys, a mature search, an inbox your agents will not fight, integrations with whatever else you run, and on three of the four an AI agent that resolves conversations on its own, which is a real product, not a checkbox.
- Working on day one, with search, routing, and reporting already good rather than described
- Email, chat, phone, and social arriving in one queue, which is weeks of work you never scope
- An AI agent that resolves conversations unaided, and this template has no version of that at all
- Integrations with your billing, your CRM, and your issue tracker, already written and maintained
- Every one of them bills per person on your team, so the cost of support grows with your headcount
- Three of the four bill again per answer, which prices the exact thing you are trying to increase
The category default, and the longest ladder. The page quotes each tier as “agent/month paid yearly” and advertises “20% off annual”, so month-to-month runs higher than every figure here. The top tier, Suite Enterprise + Copilot, publishes no price at all and sends you to sales. On AI it states the model without the rate: “Paying per automated resolution means that you pay only for customer requests that were successfully resolved by the AI agent.” We also opened its AI product page looking for that rate and it publishes none, so none is quoted here. Note where the knowledge base sits: not on the $19 tier, but from Suite Team at $55.
zendesk.com · checked August 2026
The cheapest top tier of the four, and the one that sells AI by the block rather than by the answer. All three plans state “First 500 sessions included”, then “$49/100 sessions”. The AI Copilot that helps your own agents is a separate “$29/agent/month billed annually”. The page shows “Save 20% Annually” and no monthly figures. Two details worth knowing: temporary agents are sold as day passes from $2 to $12 depending on tier, which is unusually honest pricing for seasonal support, and while the page’s own description mentions a free program for two users, nothing in the page itself documents it, so no free tier is claimed for Freshdesk here.
freshworks.com · checked August 2026
Included because it states the per-answer model more plainly than anybody else. Fin is “$0.99 per outcome”, and the page defines one: “An outcome is counted when: A customer confirms their issue is resolved, or They don’t ask for more help after Fin responds, or Fin completes a workflow (Procedure), including handoffs”, with “You’re only charged once per conversation, even if multiple questions are answered.” Do that multiplication before comparing seat prices: a thousand resolved conversations a month is roughly $990, on top of every seat. Fin will also run on top of a help desk you already have, with no seat cost and a minimum monthly commitment.
intercom.com · checked August 2026
The small-team end, and the only one of the four with a free tier we could confirm on the page: no cost, five users, one inbox, one Docs site. Paid plans are “per user/mo” with annual billing shown at −16%, and AI Answers is a separate add-on at “$0.75/resolution”. One line the entry prices hide: Pro’s seat count is “Unlimited (minimum 10)”, so the cheapest Pro bill is ten seats whether or not ten people work tickets. Genuinely the closest of the four to what a small team needs, which is exactly why the per-resolution meter is worth noticing on it.
helpscout.com · checked August 2026
Rule of thumb: if support is your product’s front line and several people work it full time, buy. Routing, SLA timers, an omnichannel inbox, and a genuinely good AI agent are worth real money, and none of them is a weekend of describing. If the shape of your problem is that the same twenty questions keep arriving and you would like people to stop having to ask them, you are renting a queue to solve a library problem, and the library is the half you can own. One more finding worth weighing before you decide either way: in a Gartner survey of 5,801 customers in early 2025, 60% of agents failed to promote self-service at all, and when agents did mention it, a doubling in the number of customers likely to use it next time followed. The cheapest deflection in any support product is an agent answering with a link to the article, and no plan tier sells it to you.
Why build with Claude Code
Most software looks simple from the outside, but it’s mostly hidden plumbing: a database, logins, permissions, validating forms, and dozens of screens that read and write records. Building all of that yourself means being fluent across the full stack, so weeks go to parts customers never see before the first real feature works.
Claude Code removes that barrier. The whole workflow becomes a simple loop:
Describe
Say what you want in plain words in any language.
Build
It writes and edits real code across backend, auth, and UI.
Check
Run the app and see the change actually work.
Repeat
Ask for the next thing. Repeat.
No stage of that loop asks for the full-stack expertise or the months of boilerplate that stop most people, which is why one person can ship a working app in a couple of weeks.
Three hard partshandled for you
The data model, authentication, and access rules are what make software like this genuinely hard to build by hand. Describe them and Claude Code scaffolds all three. After that, the rest is mostly screens on top.
Any language is the interface
No code to write, and no English required either. Whether you need a new field, a renamed step, or an AI summary, describe it in whatever language you think in and Claude Code handles the implementation.
Whole project in context
It finds and reads the files a change touches, instead of needing you to paste them in, so each edit stays consistent with what is already there. Point it at the two or three files that matter and it stays fast.
Pay a developer, or do it with AI
The only running costs are a database plan and hosting, and both start free. If you add an AI feature, you pay its model provider for the text you send, and nothing else on this page is metered.
Hire a developer
Custom build, from scratch- Developer
- ~$13k-$53k
- Supabase (backend)
- Free tier · $25/mo (Pro plan)*
- Hosting
- $0 free tier
- Build time
- ~265 hrs of their work
~$13k-$53k to build, then from $25/mo after launch
Our ~265-hour estimate, priced against the rate survey linked below. That survey puts senior US developers in the $100-$150+/hour bands and notes the 20-40% an agency adds over them, so $50/hr and $200/hr bracket the realistic ends. Where the hours land is the part worth reading twice: search, live chat, and four roles’ worth of access rules account for roughly a third of them, and not one of those three appears in a screenshot, which is the usual reason a quote for a help desk comes back higher than the mockups suggest.
Build it with Claude Code
From scratch, with Claude Code- Claude Code
- $20/month (Pro) to $200/month (Max)
- Backend (Supabase)
- Free tier · $25/month (Pro plan)*
- Hosting
- $0 on a free tier
- Your time
- ~126 hrs
~$20-$200/month while you build, then whichever plan you keep using
Claude Code itself is free. The cost sits in the Claude plan behind it. The fee doesn’t shrink when you start from a template the way a per-hour developer bill would: Pro, at $20/month, covers a template import or a short build, and a from-scratch build that runs for weeks tends to need the $100-$200/month Max plan instead, because it outlasts Pro’s usage window. Either way, the template changes how many of the hours in the estimator above you actually spend, not which Claude plan you’re paying for.
* One line on the free tier matters more here than on most builds, and it is not the database size. Supabase Free comes with 500 MB of database space, 1 GB of file storage, and 5 GB of monthly egress. Articles and tickets are text and will not trouble any of that for years. What will is attachments: a support queue collects screenshots and PDFs, and 1 GB of them arrives faster than you expect. Free also pauses a project after a week without activity, which for a help center means the week you launch it and nobody has found it yet. Pro, from $25/mo, ends the pause, brings 250 GB of egress (then $0.09 per GB), and keeps a daily backup for 7 days.
What changes is which way the bill points. A rented help desk gets more expensive as your team grows and as more questions get answered. One you own costs the same either way, and the money moves to whichever AI model you choose to call and how much text you send it. The second shape suits a product whose support volume is going up, which is most products that are working.
Prices and rates from supabase.com, developex.com and claude.com, checked August 2026.
Decide before you build
Six things to settle in writing before anything gets built. Every one of them is a promise you are making to somebody who has a problem with your product, and every one costs far less to decide now than to unpick after your team has spent three months working a queue whose shape nobody ever chose.
Whether asking for help requires an account
Settle this before the schema, because it reaches into every table. An account gives somebody their own history, which is where most follow-up questions get answered without you, but requiring one before they can report a broken checkout loses you the report. The middle path: accept the question from any email address, then let them claim it afterwards.
What resolved means, and who is allowed to say it
A status list is a workflow in disguise, and waiting on the customer is the state people forget. Without it your queue cannot tell an unanswered ticket from one waiting on a screenshot. Decide the list, whether an agent may close what the customer has not agreed is fixed, and what happens to a ticket nobody has touched in a fortnight.
Whether you are staffing a live chat at all
A rota question rather than a code question, and the expensive one to get wrong. A chat window implies somebody is there. If nobody is at 9pm it has to say so and turn into a ticket, by design rather than by accident. No chat and honest response times beats a chat nobody watches.
Which languages, and who owns the words
Translating the library is the cheapest way to serve customers who do not write in your language, and it changes the data model: an article becomes versions per language, each published or not, current or stale. Decide which languages, and who signs off a machine translation. An automatic translation of your refund policy is still a policy statement.
What people may attach, and what you do with it
Screenshots are how customers explain things, and a screenshot of an order confirmation carries a name, an address, and sometimes rather more. Decide the file types and size limit, who may open an attachment other than the sender, and how long you keep them.
Where email fits, given what it costs you
Support is the one product where people expect a reply to arrive without them checking. In-app notifications work while a customer is signed in. Email reaches somebody who filed a ticket and went back to work. A reply nobody sees is the most common reason a queue feels slow when it is not.
Comparing your build options
Two parts of this app look like pages and behave like systems, and your starting point decides how much of the estimate they eat. Three ways to arrive at the same product: by hand, on a UI kit whose search stops at titles, or through Claude Code end to end.
Two of these parts are much larger than they look from a screenshot. Search has to be good enough that somebody stops typing and starts reading, and live chat is a real-time application wearing the same clothes as the rest of the app. Neither is a screen you can finish in an afternoon.
A starter kit gives you a document list, a form, and a dashboard shell. It has no opinion about whether an article answers the question somebody typed, no notion of an article that exists in three languages, and nothing that keeps four kinds of account out of each other’s records. All of that is still yours.
Ask for one piece at a time and the migration, the search function, and the screen reading it all arrive as one change. The same task list, worked by an agent that reads the rest of the project before it touches any of it.
Estimate your exact build timeframe
Plenty of teams need less than this. If you have no intention of staffing a live chat, or your customers all read one language, untick those and watch the estimate drop.
Your estimate
126 hrs
start to finish
Based on the 7 of 7 features you’ve selected, plus ~29h 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
Four things need to be on your machine before step 01, and none of it takes more than about 15 minutes. Three are ordinary installers you click through, and the fourth is an active Claude subscription. From there, you build simply by describing what you want, in your own words.
Claude Code
Your main AI assistant. Download and run the free Claude Code CLI, connect your Anthropic account or pay-as-you-go API key, and build your app in plain English. It runs in the Terminal, and if a command line puts you off, the same tool ships as a desktop app with buttons and windows.
Install Claude CodeClaude subscription
Claude Code itself is free, but the free Claude.ai plan does not include Claude Code access at all, so you need at least Pro, unless you pay as you go through a Console account instead. Pro at $20/month is enough to start with, though a long, from-scratch build tends to outrun what Pro allows in a given stretch, which is when people move up to Max, from $100/month. Every plan’s usage resets on a rolling window, so on a heavy day you may hit a limit and have to wait it out.
Compare Claude plansNode.js engine
The engine that runs your app on your own computer. You never have to learn how it works: download the version marked LTS (the most stable one), install it, and forget about it.
Download Node.js (LTS)Supabase (database)
Where your project keeps its data. Install it, then sign in once by running supabase login. Words like migrations and row-level security turn up later in the guide, and Claude Code writes those parts for you.
Install Supabase CLINothing here is worth memorizing. These four just need to exist on your machine. From step 01 on, you say what you want and Claude Code runs the commands.
Build your support desk, prompt by prompt
There is no code for you to write: you describe what you need and Claude Code runs the commands itself. Pay attention to the order, though. The library and its search get built before any account exists, because a help center whose search does not find things is a contact form that nobody needed a library for, not a partly-working product.
- 01
Get it running, then write the rules down
An app booting against your own database, and a CLAUDE.md carrying the two constraints that every later step in this build depends on.
PromptSet up the projectSet up a new React 18 + Vite + TypeScript project with Tailwind and the Supabase JS client. Read VITE_SUPABASE_URL and the publishable key (the sb_publishable_… key, which replaces the older anon key) from .env, and add .env to .gitignore in the same step so neither value reaches GitHub. Add a typed Supabase client under src/lib, then write a short CLAUDE.md describing the stack and fixing the vocabulary for a help center and support desk (article, category, FAQ, translation, ticket, message, chat session, agent, editor) and recording two standing rules: whether an article is published is decided in the database access rules rather than in whichever query happens to be reading it, and every list of somebody else’s records (tickets, chats, attachments) is narrowed in the database rather than in a component, with a real-time subscription counting as a list.
Put both rules in the file, not just in this message. Everything built after this point assumes them, and narrowing a ticket list inside the component is precisely the shortcut any assistant will reach for the moment an agent inbox needs one more view of the queue.
- 02
Model the library, then put a help center over it
Articles, categories, FAQs, and translations, with the public reading side over them. No accounts yet, which makes this the cheap place to find out your categories do not match how people actually ask.
PromptModel the library and build the help centerWrite the data model as Supabase migrations, with no authentication yet. Categories with a name, a slug, and a description. Articles belonging to a category, with a title, a slug, a Markdown body, a published flag, a view count, and helpful and unhelpful counts. FAQs with a question and an answer. Separate translation tables for articles, categories, and FAQs, each row carrying a locale and its own published flag, so a translation can exist as a draft while the original is live. Seed six categories and about twenty articles in a mix of lengths, including two with a Spanish translation and one left as a draft. Then build the public side: a home page, a category page, an article page that renders the Markdown with related articles under it, and a searchable FAQ. Let me click through and tell you where the category structure is wrong before anything depends on it.
Seed a draft article and a partial translation on purpose. Those two rows are what later prove your access rules work, and inventing them now is much easier than remembering to create them at step 05.
- 03
Make search good enough that people stop typing
The step that decides whether this app works, and the one most builds treat as a text input. Search the body text, not the titles, and test it with words that are not in your articles.
PromptMake search actually workBuild search properly, using Postgres full-text search rather than a LIKE over titles. Add a generated tsvector over each article’s title and body, weight the title higher, index it, and expose a search function that takes a phrase and returns ranked results with a highlighted snippet of the matching text. Search FAQs in the same query and label which is which. Add a category filter and handle a misspelt word gracefully rather than returning nothing. Then two things I want to see: search for a phrase that appears only in the middle of one article’s body and show me it comes back, and give me a short list of queries that return nothing so I can see where the library has holes.
Ask for the list of queries that find nothing. That list is the most useful report this application will ever produce: your customers telling you which articles do not exist yet. It costs nothing to build while search is already open in front of you.
- 04
Open the queue, and put the library in front of it
Tickets with a real timeline, attachments, and the one screen worth over-building: the contact form that suggests an article while somebody is still typing their problem.
PromptOpen the queueBuild the ticket side. Tickets carry a subject, a body, a category, a status of new, assigned, waiting on the customer, resolved, or closed, a priority, the customer they belong to, and the agent assigned to them. Messages belong to a ticket and record who wrote them and when, so the ticket page is a timeline rather than a status field. Add file attachments on both tickets and messages, uploaded to a Supabase Storage bucket, capped at 10 MB, restricted to images, PDFs, and plain documents. Then the contact form, and treat it as the most important screen here: as somebody types their subject, run the search from step 03 against it and show the three best articles above the send button, so the ticket is only created if none of them answered. Add a "my tickets" list and a ticket detail page with the timeline.
The suggestion panel is the whole reason to have built search before the queue. Everything about it is a judgement call (how many articles, how soon they appear, whether it is a panel or a step), so look at it as a customer would before you move on.
- 05
Add the four roles, then prove an editor cannot read a ticket
Your library now has drafts in it, and the queue is full of other people’s problems. Four kinds of account share this database, and each one reads a different subset of nearly every table.
PromptAdd auth, roles, and access rulesAdd Supabase Auth with email and password: sign-up, login, logout, a persisted session, a profile row per account, and a useUser hook. Add an app_role enum of 'customer', 'agent', 'editor', and 'admin' with a user_roles table, kept out of the user's own metadata so nobody can promote themselves, and a SECURITY DEFINER has_role function. Then enable row-level security across every table with rules per role: a customer reaches only their own tickets, messages, chats, and attachments. An agent reaches the queue and the conversations in it but not the article editor. An editor reads and writes articles, categories, FAQs, and translations, including unpublished ones, and reaches no ticket at all. An admin reaches everything. Anonymous readers get published articles, categories, and FAQs and nothing else. Put that published condition in the policy, not in the query. Put explicit WITH CHECK clauses on every insert and update, and scope the storage bucket so an attachment is reachable only by the customer who sent it, the agent on that ticket, and an admin. Then prove three things by querying as a signed-in user: a customer cannot see another customer’s ticket, an editor cannot see any ticket, and an anonymous reader cannot see the draft article from step 02.
Ask for all three proofs as signed-in queries rather than as a description of the policies. The editor role is the one to check hardest. It is the role people hand out most freely, because writing documentation feels like a low-privilege job, and it is the one most likely to have quietly been given the whole tickets table.
- 06Destination
Live chat, the admin panel, and a shift on the queue
Real-time chat, the agent inbox, the admin panel and its numbers, the job that tidies up, and then the part most builds skip: work your own queue for an hour as each of the four roles.
PromptAdd chat, the admin panel, and rehearseFinish the app. Live chat first: chat sessions between a customer and an agent, messages delivered over a Supabase real-time channel rather than by polling, a waiting queue an agent picks from, a clear state for when no agent is available that turns the conversation into a ticket instead, and the same access rules on the real-time channel as on the table. Show me somebody subscribing to a conversation they are not part of and receiving nothing. Then the agent inbox with assignment and filters, the editor’s article editor with drafts, publishing, and CSV or Markdown bulk import, and the admin panel over users, roles, categories, and settings. Add analytics: article views, helpful and unhelpful counts, ticket volume by category and status, and the list of searches that returned nothing. Add a scheduled function that closes tickets nobody has touched in a period I set, protected by a shared secret rather than a sign-in. Then take me through a whole shift: search as a stranger, fail to find something, open a ticket with a screenshot, answer it as an agent, escalate a chat, write the missing article as an editor, and check as an admin that every number agrees with what just happened, fixing whatever breaks on the way.
Do the rehearsal as all four roles in four browser profiles, not by switching your own role. Signing in as one person and changing their role is exactly the path that hides a broken policy, because your session already carries permissions the next person will not have.
Why customer data stays private by default
Support desks hold sensitive customer chats, private attachments, and internal notes. Pre-configured database security isolates customer data, enforces strict user permissions, and prevents data leaks.
Let the auth service do the passwords
Hand the whole of sign-up, sign-in, sessions, and password resets to your database provider’s auth service. It is a solved problem you gain nothing by re-solving, and the failure modes when it is written from scratch are silent ones. Keep it to email and password, too: somebody contacting support is already having a bad day, and an unfamiliar sign-in method standing between them and the report is a report you never receive.
Four pre-configured user roles
The template ships customer, agent, editor, and admin. A customer reaches their own tickets and chats and nothing else. An agent reaches the queue and the conversations in it. An editor writes and translates the library but has no business reading a stranger’s ticket. An admin runs users, settings, and the reports. That third role is the one people collapse into admin out of convenience, and it is worth keeping separate: writing documentation is a job you hand to more people than you hand the customer list to.
Database-level security (Row-Level Security)
A ticket list that narrows its results in the component is one forgotten condition away from putting somebody else’s problem, name, and email address on screen. Row-level security relocates that judgement to the moment the database hands rows out, and the point of moving it is what happens when somebody forgets: an unscoped query comes back empty rather than coming back with everything.
89 policies, because four roles read every table differently
The template ships 89 row-level security policies, and the count is structural rather than anxious. Take one table, tickets: the customer it belongs to may read and add to it, the agent it is assigned to may work it, an admin may see all of them, and an editor should see none. That is four rules on one table, and this application has more than twenty tables.
A draft is not a document with a flag on it
The moment your library has unpublished work in it, published status becomes a security property rather than a display property. An article table where anybody can read every row will happily serve a half-written policy page to a customer, or to a search engine. Put the published condition in the policy, not in the query that happens to be reading it today.
Real-time subscriptions are queries too
This one catches people, because it does not look like a data-access question. A chat that pushes messages to whoever is listening needs the same access rules as the table it reads from. Otherwise the way to read a conversation you are not part of is to subscribe to it rather than to query it. Ask specifically whether the real-time channel enforces the same rules as the table, and ask to be shown it refusing.
An attachment is a file, not a row
Files live in storage, which has its own permission model, and the default on most buckets is more generous than the default on a table. A support attachment is exactly the wrong thing to serve from a public URL: it is a screenshot somebody sent you privately, and a link that works for anybody who has it will eventually be somewhere you did not put it. Scope the bucket to the ticket it belongs to, cap the file size, and decide which types you accept.
Keep the role off the account record
The four roles need a table of their own, and the reason is narrow: anything stored on an account can be edited by the person that account belongs to. Put the role there and a customer is one profile update away from calling themselves an agent, and an agent reaches every other customer’s tickets, chats, and attachments.
Some rules cannot live in a policy
Creating a user and giving them a role, calling an AI model with your own key, and sweeping up tickets nobody has answered are each several operations at once, and each has to be permitted to do more than the person who triggered it. The template gives 4 of those their own server-side edge function, running above the access rules and carrying the rule in its own code. That is what lets the policies stay as strict as they are without any of these three becoming impossible.
A scheduled job needs its own secret
The one that closes tickets nobody has touched is not called by a person, so it cannot be protected by a sign-in. It gets a shared secret instead, checked on every call, and that secret belongs with your other server-side secrets rather than in the code. A scheduled endpoint with no check on it is a public endpoint that changes your data, and it will be found.
Automated backups & disaster recovery
No backup is taken of your articles or of a single conversation your team has had. Daily backups, kept for a week, start on Supabase Pro at $25/mo. The library is what makes that urgent here rather than merely prudent: a year of articles is a year of your team working out how to explain things, and nothing else in your business holds a second copy of it.
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.
Run this before launch to make sure nobody can see data they shouldn’t.
The one rule that matters: the database service key, any AI provider key, and the shared secret protecting your scheduled job never belong in the app or in a public repo. If one of them gets out, assume it is compromised and rotate it that day.
What speeds the build, and what slows it
Speeds the build
- A CLAUDE.md notes file that spells out your setup and preferences
- Asking for a plan first on anything that touches several files
- One change per request, small enough to describe in a sentence
- Pointing it at the two or three files that matter
- Running the app and checking each change before the next
- Saving a working version (a git commit) after each step, so you can undo
Slows the build
- Vague prompts like “make it better”, which leave it guessing what you meant
- Asking for a whole feature in one giant prompt
- Dumping the entire project into the chat at once
- Skipping the notes file, so it forgets your conventions each session
- Accepting changes without running or reading them
- No saved versions to roll back to when something breaks
Git: what it is, and why you need it
Before you build anything, meet the one tool that makes building safe. You need no coding background for it: Git remembers every version of your project, so you can try things, break things, and get back to a working state in seconds.
What Git actually is
Git is a quiet recorder that runs alongside your project. Each time you save your work it keeps a full snapshot, so the entire history of your project lives on your computer, not just whatever the files look like right now.
Why you need it
Claude Code runs inside a permission mode you choose, either asking before each change or working more freely once you trust it. Either way, experiments sometimes still break things. Git is what makes that safe: there’s always a working version to return to, so you can try bold changes without the fear of losing what already works.
A commit is a save point
Each commit is a snapshot with a short note, like “added the home page”. Make one after every working step and you can jump back to any of them later.
GitHub’s beginner guide to GitUndo anything, safely
If a change breaks something, you roll back to the last good commit instead of unpicking it by hand. It’s the safety net that makes bold experiments with Claude Code low-risk.
GitHub is Git’s home online
Git lives on your computer. GitHub is a free, private cloud copy of the same project. It’s your backup if your laptop dies, and the place Claude Code can always get back to. Keep it private, and never commit secret keys or passwords.
Create a free GitHub accountYou rarely type git commands
You do not have to memorize any of it. Ask Claude Code to “commit this” or “undo the last change” and it runs the git steps for you. Prefer clicking to typing? Claude Code’s own desktop app, which you install separately, shows each change side by side before you keep it, and GitHub Desktop gives you plain buttons for saving and rolling back.
Get the Claude Code desktop appWhere 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 once and every push goes live on its own, with nothing to configure for a Vite project. Read the plan terms before you point a company domain at it: Hobby permits personal, non-commercial use only, so a help center for a product you sell belongs on Pro at $20/user/mo. | Pro from $20/user/mo (Hobby is non-commercial) |
| Netlify | Drag-and-drop or Git | Connect the repository, or drag the built folder onto the page and be live in about a minute. It needs one redirect rule so a link straight to a single article opens that article rather than a not-found page, which matters more here than on most builds, because a link to one article is how most of your readers will arrive. | Free tier |
| Cloudflare Pages | Readers in several countries | Copies of the site sit near your visitors rather than in one place. Worth choosing if you have translated the library, since the reason you translated it is that your readers are somewhere else. | Generous free tier |
| GitHub Pages | Not really this app | Free publishing straight out of your GitHub project, after changing one routing setting. Listed mainly to be ruled out: publishing free requires the repository to be public, and this one sits alongside an app holding your customers’ questions and attachments, so the free path is one you would not want to take. | Free from a public repo only |
| Firebase Hosting | Teams already on Google | Set it up once, then release with a single command each time. The reason to choose it is almost always that your other accounts are already Google ones. | Free Spark tier |
| AWS Amplify Hosting | Teams already on AWS | Publishes from the AWS console, with one rewrite rule so a direct link to an article resolves. Worth choosing when AWS is already on your invoices and you would rather not add a vendor. | Free tier (build + hosting) |
| Surge | Publish from the terminal | One terminal command puts the built folder online, with no repository anywhere in the process. Good for showing a colleague what the help center looks like, though not for the address you put in your product’s footer. | Free - unlimited publishing |
| DigitalOcean App Platform | DigitalOcean users | Builds and serves from the account that already holds whatever else you run. That consolidation is the whole reason to pick it over the rest of this list. | Free - 3 static sites, 1 GB/mo transfer |
All of them will serve the app perfectly well, so judge them on three questions instead of one. Whether the plan permits commercial use, since Vercel’s Hobby tier does not and a help center for something you sell is commercial by any reading. Whether it can publish from a private repository, because this code sits next to an application holding your customers’ questions and whatever they attached to them. And whether you can put it on a subdomain of your own product’s domain, which matters more on this build than on any other in the catalogue, for the reason directly below.
Of every app in this catalogue, this is the one that has to be findable. Half the value of a help center is that somebody searching for your product’s problem lands on your answer rather than a forum thread from 2019, and that only happens if every article has its own real URL that returns the article, not a home page with the content swapped in by JavaScript. So: add the redirect rule your host asks for, check a direct link to a deep article in a fresh browser window before you announce anything, and host it on your own domain rather than a vendor’s subdomain, because the reputation the pages build belongs to whichever domain they sit on.
Keep your data in Supabase
Articles, tickets, chats, accounts, and every file somebody attached. This is also where the rules that outrank the person asking live, and where the scheduled job that tidies up your queue belongs.
| Service | Best for | Notes | Free tier |
|---|---|---|---|
| Supabase | Data, auth, functions, files, real-time | The library and the queue sit in Postgres, all four kinds of account come from its auth service, the chat messages travel over its real-time channel, the attachments go into its storage, and its edge functions carry the jobs that have to be permitted more than the person triggering them: creating a user with a role, calling an AI model with your key. Setup amounts to opening a free project and handing the app its URL and publishable key. One piece belongs here rather than with your host: the scheduled job that closes tickets nobody answered. A static host serves files and cannot run anything on a timer, so that schedule lives beside the database. | Free tier, then usage-based |
Where AI genuinely helps a support team
Each of these is one more prompt once the library and the queue work. All five go through one server-side function holding your provider key, which is how the template already works, its translation feature being exactly that function.
Translate the library into the languages people write to you in
The cheapest way to serve customers who do not read your language, and the one AI feature this template already ships. Translation is also the safest starting point, because a human still approves the result before a customer sees it.
Add a "Translate" action on an article that sends its title and body to my ai function and stores the result as a draft translation for the language I picked, never as a published one. Keep the article’s structure (headings, lists, and links stay where they are) and leave any product names, code, and UI labels I have marked as do-not-translate exactly as they were. Show it beside the original for approval before anything publishes, and mark a translation stale when the source article changes afterwards.
Turn a solved ticket into the article that stops the next one
The best help articles are already written, badly, in your ticket history. Somebody explained the fix properly at 4pm on a Tuesday and then the explanation went into an archive nobody reads. This is the feature with the most compounding value in the whole list.
Add a "Draft an article from this" action on a resolved ticket. Send the conversation to my ai function and get back a draft article: a title phrased the way a customer would search for it, the steps that actually fixed the problem, and a suggested category from my existing list. Strip every specific detail first (names, email addresses, order numbers, account identifiers, and anything in an attachment) and save it as a draft for an editor to approve rather than publishing it. Where the fix depended on something specific to that customer, say so in the draft instead of writing a general instruction that will not work for anybody else.
Put the right article in front of the agent, mid-reply
The finding that most agents never mention self-service is not laziness, it is that finding the right link mid-conversation costs more than typing the answer again. Remove that cost and the behaviour changes on its own.
While an agent is reading a ticket, retrieve the three most relevant published articles for it and show them beside the reply box with a button that inserts a link and a one-line summary into the draft reply. Do the retrieval against my own published articles only, in the language the customer wrote in, and pass just those articles to my ai function for the summary line. Never invent an article that does not exist, and show nothing rather than a weak match. A bad suggestion costs the agent more attention than an empty panel does.
Answer from your own articles, and only from them
This is the feature the vendors charge per resolution for, and it is buildable, with more care than anything else here. An assistant that answers from your library is useful. One that improvises a refund policy has made a commitment on your behalf. Read the last line of the prompt below as the point of the feature rather than a caveat on it: the log of questions it could not answer is worth more than the answers.
Add an assistant on the help center that answers only from my published articles. Retrieve the relevant articles first and pass their text to my ai function, and constrain the answer to what is in that text: no general knowledge, no inference. Every answer cites the articles it came from as links the reader can check. When the retrieved text does not contain the answer, say exactly that and offer the contact form rather than attempting one. Never state a policy on refunds, delivery, warranty, cancellation, or account closure that is not written verbatim in the source it was given, and log every question it could not answer, because that log is my list of articles to write.
Ask what this week’s tickets were actually about
Your reporting answers the questions you had when you built it. What turns up later is which release caused the spike, whether the new pricing page created work, and which twenty questions are one missing article.
Add a panel on the admin dashboard that groups the last period’s tickets and chats by what they were about, using my ai function, and returns the themes with a count each, a representative example per theme, and, where the theme maps to nothing in my library, a suggested article to write. Send the subject and body text with names, email addresses, and order numbers removed, never attachments, and state the counts as figures rather than describing them vaguely. Print the period it covered beside the result so I am never reading last month as though it were this one.
Each prompt above picks the model that fits the job. As a rule of thumb, that is Haiku for high volume, Sonnet for everyday writing, and Opus for deeper reasoning. Model names move faster than this page does, so check the current list in the Claude docs (linked in the references below) before you build. Send every one of these prompts through that same ai function, so one key and one set of rules governs all of them.
Get a head start with our template
All of the above starts from nothing, and nothing is not the only place to start from. This app is already built and already working, which turns the weeks that search, chat, and four roles’ worth of access rules would take into an afternoon of loading in your own articles.
Help Center & Support Desk
The exact support desk this guide builds, packaged so you can open it, point it at your own backend, and make it yours from there. A help center and support desk in one, so customers can find answers themselves and your team handles the rest. Articles and FAQs cut down the repeat questions, tickets and live chats land in role-scoped dashboards, and an admin panel keeps users, content, and analytics in one place.
The key benefits of starting with a template
The search already searches the body text and the chat already arrives in real time. That is most of what this saves you. Behind it, the ticket timeline, the attachments, the translations, the analytics, and a four-role permission model are done too.
Building the core from scratch
~126 hrs
Opening the template, already built
~1 hr
~125 hrs of building you skip
Two different things, measured deliberately. The ~126 hrs buys you the application. The ~1 hr is what it takes to open the finished one, point it at a database of your own, and get a first category of articles into it. Writing those articles is work either way, so it sits outside both numbers.
A help center that already answers
Articles in categories with search across the body text, a FAQ of its own, related articles under each one, was-this-helpful voting that counts one vote per reader, comments, and a contact form that suggests likely articles by keyword while somebody is still typing their question, the screen where a ticket does not get opened.
A queue and a chat, both finished
Tickets with a full timeline, five statuses including the waiting-on-the-customer one people forget, file attachments up to 10 MB on tickets and chats, a shared agent inbox with assignment, live chat between a customer and a human agent, direct messages between staff, and a scheduled job that closes what nobody has touched.
Four roles enforced 89 ways
Customer, agent, editor, and admin accounts with 89 row-level security policies behind them, so an editor writing the library cannot read a stranger’s ticket and a customer cannot reach anything but their own, plus 4 server-side functions for the rules that have to outrank the person asking, and a per-user set of notification preferences on top.
Translations and analytics, already wired
Per-article, per-category, and per-FAQ translations with a one-click AI translation into Spanish, French, and German through a server-side function that is the only place your provider key exists, and article views, helpfulness scores, and ticket volume charted in the admin panel, which is where you find out which article to write next.
A codebase your AI tool can keep extending
Types everywhere, files grouped by the feature they belong to rather than by what kind of file they are, and a comment anywhere the reasoning would not be obvious to somebody meeting the code for the first time. The access rules are where that pays: with four roles spread over twenty-odd tables, a change that ignores the pattern already in place is how one customer ends up looking at another customer’s problem.
From founders who build on our templates
The distance between an idea and a live, production-ready system used to be massive. This foundation collapses that gap entirely. It allows us to deploy enterprise-grade tools at the speed of thought.
Jeevan ThomasFounder & CEO, Hado.aiCommon questions
No, and this is the most important thing to know before you compare it with anything. The chat in this template connects a customer to a human agent, a real-time conversation, not an assistant answering on your behalf. The only AI in it is article translation. If what you want is an assistant that resolves questions unaided, that is a feature to build (the AI section above has the prompt and the constraints it needs), and it is the same feature three of the four vendors above charge per resolution for.
Not as it stands, and it is worth deciding about early. The template notifies people inside the app and keeps a per-user set of notification preferences, but it carries no outbound email anywhere. The contact form writes a ticket and stores its attachments rather than sending a message. Connecting an email service is a small, well-defined addition, and one to make before real customers use it: on a support desk, a reply the customer never sees is the most common reason a fast team feels slow.
No. That is the half an AI coding tool is strongest at. Say what you want in ordinary language and out come the tables, the four kinds of account, the rule deciding what each of them may reach, the real-time channel carrying the chat, and the server-side functions for the jobs that have to be permitted more than the person who triggered them. The only part left to you is opening a free Supabase project for it all to be written into.
Reading, yes: the whole library, the FAQ, and the search are open, which is the point of a help center. Opening a ticket in this template goes through an account, so a customer can come back and follow their own request. Accepting a question from anybody with an email address and letting them claim it into an account later is a described change rather than a rebuild, and it is the right one if a lot of your questions come from people who are not customers yet.
The translation feature ships pointed at Spanish, French, and German, and adding a language is a change to one map in one server-side function rather than a new feature. On quality: a machine translation of a how-to article is usually fine, and a machine translation of your refund policy is a policy statement in another language, which is why the template stores translations for approval rather than publishing them. Decide who signs those off before you switch it on.
Yes. Bulk import takes CSV and Markdown files, with a Markdown file split into separate articles on its top-level headings, which is close to how most existing documentation is already stored. Anything in another format is a conversion into one of those two rather than a manual re-typing, and it is worth doing properly: the library you import is the asset, and article number fifty is where search starts to matter.
Rules in the database rather than filtering on the page: 89 of them across the tables, which is what four roles over twenty-odd tables comes to. The one worth asking your AI tool to prove is the chat: a real-time subscription is a query too, so ask to be shown somebody subscribing to a conversation they are not part of and getting nothing. A demonstration rather than a description, because that is the check people skip.
A place to keep the data and a place to serve the app, and both have a free tier. The upgrade worth making once real customers depend on it is Supabase Pro, from $25/mo, not because articles and tickets are large, since they are text, but because attachments are, and because a free project goes to sleep after a quiet week. Beyond those two lines nothing here grows with the size of your team or with how many questions you answer. Add an AI feature and you pay whichever model you call for the text you send it, which bills quite differently from paying per answer.
Yes, and it needs no structural change to do it. The customer role becomes the employee filing a request, agents become whoever handles them, and editors write the internal documentation. Two things are worth adjusting: restrict sign-up to your own email domain, and think about which roles may read which tickets, since an internal desk mixes IT requests with things people would rather their colleagues could not read.
Nothing here is proprietary. Your articles, tickets, and conversations sit in plain PostgreSQL tables, which any Postgres host will accept from a standard dump, and the attachments are files you can copy like any other files. That is worth more in this category than most: a support archive is years of your team’s accumulated answers, and it is exactly the asset that makes a platform expensive to leave.
Yes, and here it is worth more than reassurance. Every host listed above attaches a domain in a few clicks with HTTPS included, and the pages you are about to write are meant to be found by people searching for your product’s problems, so putting them on a subdomain of your own site means that traffic and that reputation accrue to you rather than to a vendor’s. It is the difference between building an asset and renting a shelf.
No, though you will type the occasional command: installing Claude Code, starting the app, applying a database change. The setup section above lists what you need, with a link for each, and once it’s on your machine Claude Code runs most of those commands for you.
Claude Code turns the real code into an app you can publish, with a database and user accounts. An Artifact is a one-file preview, good for a quick look but not for going live.
Claude Code’s plans reset on a rolling window rather than billing per token, so a heavy day of building can bump into a limit. You either wait for it to reset or move up a plan. Max gives more headroom for a long, from-scratch build. Nothing you’ve already built is lost either way, so the work only pauses.
References
Sources checked August 2026- 01Only 1 in 7 customer service queries resolved with self-service (Gartner survey, August 2024). cxtoday.com (Gartner survey published August 2024)
- 02Only 14% of customer service issues are fully resolved in self-service (same Gartner survey, second read). destinationcrm.com (published September 2024)
- 0360% of customer service agents fail to promote self-service (Gartner survey, 5,801 customers, early 2025). directorsclub.news (published June 2025)
- 04Pricing (per-agent tiers, Copilot add-on, per-automated-resolution AI billing), Zendesk. zendesk.com
- 05Pricing (per-agent tiers, AI agent sessions, day passes), Freshdesk. freshworks.com
- 06Pricing (per-seat tiers, Fin per-outcome pricing and its definition), Intercom. intercom.com
- 07Pricing (free tier, per-user tiers, AI Answers per resolution), Help Scout. helpscout.com
- 08Pricing (Pro plan, egress, backups, free-tier pause), 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
- 12Realtime authorization (access rules on subscriptions), Supabase docs. supabase.com
- 13Plans and pricing (Pro, Max), Claude. claude.com
- 14What is the Max plan?, Claude support. support.claude.com
- 15Set up Claude Code, Claude docs. code.claude.com
- 16Models overview, Claude docs. platform.claude.com
This guide is general information, not legal advice. What you may keep in a support record, how long you may keep an attachment somebody sent you, and what a customer may ask you to delete vary by country and by state, so check your own rules before you collect anything. 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, so confirm before you budget. Build hours and the cost estimates derived from them are our own estimates, not quotes. Claude, Claude Code, and the Anthropic API are products of Anthropic. Verify current capabilities and pricing before relying on them.