Front-end Deployment¶
Applies to: All subscriptions
Purpose¶
Produce the web application bundle and publish it so the reverse proxy can serve it. The two things that most often go wrong here are build-time configuration baked in wrongly, and browsers holding a stale bundle after an upgrade.
Audience¶
System administrators and implementation engineers.
Prerequisites¶
- Install on Windows Server complete
- The API reachable and its public URL known
- Identity configuration values available, where browser sign-in uses an external identity provider
Steps¶
1. Understand what is being built¶
The front end is a single-page application compiled to static files — HTML, JavaScript, CSS and assets. It holds no server-side logic and no secrets. Every piece of data it shows comes from the API.
Two consequences:
- It can be served by anything that serves static files: the reverse proxy, a web server, or a content delivery network.
- Anything compiled into it is public. Build-time configuration is visible to anyone who opens the browser's developer tools. Never place a secret in front-end configuration. Identifiers such as a client identifier are fine; a client secret is not.
2. Set build-time configuration¶
Front-end settings are read at build time, not at run time. Changing one means rebuilding, not restarting.
| Setting | Purpose |
|---|---|
| API base URL | Where the application sends requests. Wrong here and every call fails at the browser |
| Identity provider client and tenant identifiers | Only where browser sign-in uses an external identity provider |
| Any development-only convenience flags | Must be absent or false in production |
Check the last row explicitly before a production build. A development convenience left enabled in a production bundle is a security defect, not an inconvenience.
3. Compile the in-product help bundle¶
The in-product help content is compiled from source into a bundle the application loads. That compilation runs as part of the build.
The behaviour worth understanding: a help topic that does not exist renders nothing at all — no icon, no empty panel. That is deliberate, and it makes partial help coverage safe to ship. It also means missing help is invisible during testing. If the customer expects in-product help for a specific field or error, verify it resolves on the screen it belongs to, rather than assuming a successful build implies coverage.
Module help is packaged separately, so a tenant without a module never downloads its help. An absent module is therefore absent consistently — screen and help together.
4. Build for production¶
Produce the production build. Confirm afterwards that:
| Check | Why |
|---|---|
| The build completed without errors | Obvious, but a warning-laden build often indicates configuration that did not apply |
| Output files carry content hashes in their names | This is what makes cache invalidation work on upgrade |
| No development flags are present in the output | Search the bundle for the flag names |
| The API base URL in the bundle is the production URL | The most common front-end deployment defect is a bundle pointing at the wrong environment |
5. Publish the output¶
Copy the build output to the location the reverse proxy serves. Keep the previous build until the new one is verified — that is your fastest rollback, and it takes seconds.
| Requirement | Detail |
|---|---|
| Readable by the web server or proxy | — |
| Not writable by it | The web tier should not be able to modify what it serves |
| Previous build retained | Rollback path |
6. Configure single-page-application routing¶
The application handles routing in the browser. A user who refreshes a deep link, or opens one from an email, requests a path that does not exist as a file. The proxy must serve the application's entry page for any path that is not a real file, letting the application resolve the route.
Without this, the application works perfectly until someone refreshes a page or follows a bookmark, and then returns HTTP 404. It is the most common front-end deployment fault and it never appears during a click-through test.
7. Set cache headers deliberately¶
| Asset | Header | Why |
|---|---|---|
| Hashed JavaScript, CSS, images | Long-lived immutable caching | The filename changes when the content does |
| The entry HTML page | No caching, or must-revalidate | It references the hashed files; a cached copy pins users to the old bundle |
Getting this backwards is what produces users on a stale version after an upgrade, reporting bugs that were fixed and behaviour that no longer exists.
Validation¶
| Check | Method | Pass condition |
|---|---|---|
| Application loads | Open the published URL | Sign-in page renders |
| Correct API target | Sign in and watch network requests in the browser | Requests go to the production API, not another environment |
| Deep link refresh works | Navigate to an inner page and press refresh | The page loads. HTTP 404 means routing is not configured |
| Bookmark works | Open an inner page from a new browser tab | Loads correctly |
| No development flags | Search the published bundle for the flag names | Absent |
| Cache behaviour correct | Inspect response headers | Hashed assets cached long; entry page not cached |
| Upgrade is picked up | Publish a new build and reload in an existing browser session | New version served without clearing the cache manually |
| In-product help resolves | Open a screen where a help topic is expected | The help affordance appears and opens content. An absent icon means no entry exists for that key |
| Console clean | Open the browser console on the main screens | No errors. Failures to load configuration surface here first |
Troubleshooting¶
| Symptom | Cause | Action |
|---|---|---|
| Blank page, console shows failed requests | Bundle points at the wrong API URL, or the API is unreachable | Check the build-time API URL and confirm the API responds from a browser |
| Application works until a page refresh, then HTTP 404 | Single-page-application routing not configured on the proxy | Serve the entry page for any path that is not a real file |
| Users still see the old version after an upgrade | Entry page cached | Set no-cache on the entry page. Clearing individual browsers is a workaround, not a fix |
| Some users on the new version, some on the old | Mixed cache states, or a partially updated CDN | Purge the distribution and confirm the entry page's cache headers |
| Sign-in redirect fails | Identity client identifier wrong, or the redirect URL not registered with the identity provider | Correct the build-time value and register the exact redirect URL |
| Help icons absent where expected | No help entry exists for that key | Expected behaviour — the product never renders an affordance that opens nothing. Request the content if it is genuinely needed |
| A module's screens and its help are both missing | The module is not enabled for that GSTIN | Not a deployment fault. See Modules and Licensing |
| Fonts or images fail to load | Content-security policy blocking an origin, or assets not copied | Check the console; confirm the whole build output was published |
| Downloads produce broken links | The download origin is blocked by proxy or content-security policy | Downloads are served from a different origin by design. See Domains and URLs |
Related Articles¶
- Reverse Proxy and TLS — serving these files and routing correctly
- Domains and URLs — the hostnames involved
- Post-Installation Verification — the completion gate
- Upgrade Procedure — republishing safely