A few days ago, I was going through one of my SaaS applications before shipping it.
The product worked.
The UI looked good.
The API worked.
Authentication worked.
And technically, I could have deployed it and called it done.
But opening DevTools, viewing the page source, checking how Google would understand the site, and looking at the production bundle told a different story.
A working application is not necessarily a production-ready application.
So I ended up doing a complete frontend production-hardening pass.
Here is the checklist I now use before calling a SaaS frontend ready for production.
1. Build a Proper Page Source
Modern React applications can easily produce pages where the initial HTML tells crawlers almost nothing about the application.
The browser eventually renders everything correctly, but crawlers, link previews, search engines, and other machines still benefit from meaningful HTML.
I started checking the actual page source instead of judging the application only from what React rendered on screen.
The page should expose enough meaningful information for machines to understand what it represents.
2. Build a Custom 404 Page
A default server error or blank React page is a terrible dead end.
A proper 404 page should:
- clearly explain that the requested page doesn't exist,
- maintain the product's branding,
- provide navigation back into the product,
- link to important pages,
- and return the correct HTTP status where possible.
Even error pages are part of the product experience.
3. Give Every Page a Unique Title
One of the easiest mistakes in a SPA is having every route use the same title.
For example:
My SaaS
is much less useful than:
AI Video Editor | ProductName
or:
Pricing | ProductName
Every important route now gets its own descriptive title.
This improves search visibility, browser-tab usability, bookmarks, and link previews.
4. Write Useful Meta Descriptions
I also stopped using generic descriptions such as:
The best platform for everything.
Every important public page gets a description explaining what that specific page actually offers.
Good metadata should help someone decide whether the page is relevant before they even open it.
5. Add Canonical URLs
Applications often accidentally expose the same content through multiple URLs.
Query parameters, alternate paths, trailing slashes, campaign URLs, and routing behavior can all create duplicate versions of a page.
Canonical tags tell search engines which URL should be considered the authoritative one.
A small detail, but an important one.
6. Use One Clear Primary Heading Per Page
Design systems make it surprisingly easy to build pages that look visually correct while having terrible document structure underneath.
Each page should have a clear purpose.
The primary heading should communicate that purpose.
Then the remaining headings should form a logical hierarchy.
Not because an SEO plugin says so.
Because semantic HTML makes the page easier for search engines, accessibility tools, browsers, and humans to understand.
7. Generate a Sitemap
If the application contains publicly indexable pages, I add a sitemap.xml.
It contains the canonical public URLs I actually want crawled.
The important part is not merely generating a sitemap.
It is making sure the sitemap doesn't advertise pages that should never be indexed in the first place.
8. Configure robots.txt
Then comes robots.txt.
It communicates which sections crawlers should or shouldn't access and points them toward the sitemap.
For SaaS products, this becomes especially useful when separating public marketing pages from dashboards, authenticated routes, internal tools, or temporary environments.
9. Add llms.txt
This one is newer.
Alongside traditional search-engine optimization, I also started thinking about how AI systems understand products.
I added an llms.txt file containing a concise, machine-readable explanation of the product and its important resources.
Whether llms.txt becomes a universal standard or not, the underlying idea is worth paying attention to:
websites are increasingly being consumed by machines other than traditional search crawlers.
SEO is slowly becoming broader than Google.
10. Stop Treating the Favicon as an Afterthought
That tiny icon appears everywhere:
browser tabs, history, bookmarks, shortcuts, search interfaces, and sometimes mobile surfaces.
I replaced the placeholder favicon with something simple, recognizable, high-contrast, and consistent with the product identity.
Small visual elements can have an outsized effect on how finished a product feels.
11. Add Internal Links and Breadcrumbs
A lot of SaaS landing pages behave like isolated islands.
I started deliberately connecting related pages.
Features → relevant use cases.
Blog posts → related documentation.
Documentation → product pages.
Child pages → parent sections.
Where the information hierarchy justified it, I added breadcrumbs as well.
Good internal linking helps users navigate while also helping crawlers understand the structure and relationships between pages.
12. Add Structured Data
Humans understand a page through visual context.
Machines don't always get that luxury.
Structured data gives additional context about what the page represents.
Depending on the page, this can describe things such as:
- the organization,
- software/application information,
- articles,
- breadcrumbs,
- FAQs,
- or other supported entities.
For breadcrumb-enabled pages, I also added breadcrumb structured data rather than relying only on the visual component.
13. Fix Every Production Console Error
One rule I started following:
a production browser console should be boring.
No mysterious errors.
No failed requests.
No hydration problems.
No missing assets.
No repeated warnings that everyone has learned to ignore.
Warnings have a tendency to become background noise.
And when the important error finally appears, nobody notices it.
14. Disable Production Source Maps When They Aren't Needed
Development source maps are incredibly useful.
Production source maps require more thought.
Depending on the deployment model, publicly accessible source maps can expose significantly more information about the application's source than intended.
For applications that don't need publicly shipped source maps, I disable them in the production build or upload private maps only to the monitoring platform that requires them.
15. Reduce Massive JavaScript Bundles
Then I opened the bundle output.
This is where things usually get interesting.
A beautiful landing page shouldn't require downloading a ridiculous amount of JavaScript before becoming useful.
I started looking for:
- oversized dependencies,
- libraries imported globally,
- components that could be lazy-loaded,
- routes that could be code-split,
- duplicate dependencies,
- unused packages,
- and features that shouldn't be in the initial bundle.
Bundle size is not just a Lighthouse metric.
It affects actual humans using slower hardware and slower networks.
16. Remove Every Default Vite/React Placeholder
This sounds obvious.
Yet production applications constantly ship with traces of their scaffolding.
Vite logos.
React favicons.
Default metadata.
Placeholder page titles.
Starter README text.
Example assets.
Development console messages.
Boilerplate copy.
I now search the repository before release and remove anything that makes the application look like a starter template instead of an actual product.
The Bigger Lesson
None of these changes individually feels revolutionary.
That is exactly why they get ignored.
Developers naturally focus on the difficult parts:
authentication,
databases,
payments,
AI pipelines,
background jobs,
infrastructure,
and application logic.
Then we finish the feature and mentally declare the product complete.
But production quality lives in hundreds of smaller decisions surrounding the feature.
Can Google understand the page?
Can an AI system understand the product?
Does the browser console stay clean?
Does a broken URL still feel like part of the application?
Are users downloading JavaScript they don't need?
Does the website still advertise the framework used to scaffold it?
Does every page actually explain what it is?
These aren't glamorous engineering tasks.
But together they make the difference between:
“I built a React app.”
and
“I shipped a product.”
My current pre-production frontend checklist:
- Meaningful page source
- Custom 404
- Unique page titles
- Page-specific meta descriptions
- Canonical URLs
- Semantic page headings
sitemap.xmlrobots.txtllms.txt- Product-specific favicon
- Internal links + breadcrumbs
- Structured data
- Zero unexplained console errors
- Production source-map strategy
- JavaScript bundle optimization
- Zero framework placeholders
I'm probably going to keep extending this checklist as I ship more products.
Because shipping the feature is only half the job.
The other half is making the web understand what you shipped.
Top comments (0)