Internal vs. Merchant Content Guide
This guide covers everything a contributor needs to know about the two-audience build system: what content belongs in each build, how builds are produced, how they are deployed, and how to author content correctly.
The docs-internal image contains engineering guides, architecture diagrams, admin API references, internal error details, and other sensitive operational content. This image must only be deployed to the Test environment (developers.healthsafepay.com). Deploying it to any merchant-accessible URL is a security violation. If you are unsure whether content is safe for merchants, treat it as internal and wrap it accordingly.
1. The Two Buildsβ
Every pull request targeting develop (opened, updated, or synchronized) produces two distinct container images in parallel:
| Build | Workflow | ACR image | DOCS_AUDIENCE | Audience |
|---|---|---|---|---|
| Merchant | .github/workflows/build-merchant.yml | docs-merchant | merchant | External merchants and partners |
| Internal | .github/workflows/build-internal.yml | docs-internal | internal (default) | Internal team only |
DOCS_AUDIENCE is set at yarn build time. Content is permanently baked into each image β there is no runtime flag. The two images are content-distinct.
What each build containsβ
| Content area | Merchant | Internal |
|---|---|---|
| Integration guides, API request/response schemas | β | β |
| Error codes visible to merchants | β | β |
<Audience include="internal"> inline sections | β stripped | β |
docs/05-engineering-guide/ | β excluded | β |
docs/contributing-guide/ | β excluded | β |
docs/06-high-level-designs/ | β excluded | β |
Internal wallet management operations (5-customers/) | β excluded | β |
Third-party integrations (8-third-party-integrations/) | β excluded | β |
Internal API spec (/engineering-guide/internal-api-v2/) | β excluded | β |
OpenAPI [Learn More](...) internal links | β stripped | β |
| AI Assistant (ChatBot, AI SearchBox) | β hidden | β |
2. How Deployments Workβ
The Helm values file for each GitHub Environment overrides image.repository, binding the environment permanently to one image. The deploy workflows only set the image tag β the repository is fixed by the values file and cannot be overridden by the caller.
| GitHub Environment | Helm values file | Image deployed | URL |
|---|---|---|---|
Dev | deployment/config/helm/values-dev.yaml | docs-merchant | docs.healthsafepay.com |
Test | deployment/config/helm/values-test.yaml | docs-internal | developers.healthsafepay.com |
Environment isolation is automatic. The operator only selects Dev or Test β the correct image follows. It is structurally impossible to deploy docs-internal through the Dev environment or vice-versa via the standard workflows.
Deployment approval issuesβ
After each build, the shared CI workflow creates a GitHub issue labelled deployment-requested. Comment /deploy on the issue to trigger deployment.
- The issue from
build-merchanttargetsDevautomatically. - The issue from
build-internalis automatically patched by a post-build job (fix-deployment-issue) to targetTestβ no manual action needed.
Deploying manuallyβ
If you need to deploy without using an approval issue, use the deploy-manually workflow:
- Select environment
Dev(merchant) orTest(internal). - Enter the image tag (7-char commit SHA).
- Run β the correct image is pulled automatically via the values file.
3. How Content Exclusion Worksβ
Content is excluded from the Merchant build by two mechanisms:
| Mechanism | Scope | Configured in |
|---|---|---|
| Audience exclude globs | Entire folders β never compiled | config/audience-exclude-globs.js (single source of truth) |
<Audience include="internal"> component | Inline sections within a page | Applied by authors in MDX source |
Folder-level exclude globs live in one file: config/audience-exclude-globs.js.
Both consumers import from it, so the site build and the search index stay in sync:
docusaurus.config.jsβpresets β classic β docs.excludescripts/docs/generateSearchPages.jsβ search index generation
To add or remove an excluded folder, edit only config/audience-exclude-globs.js. Do not hardcode globs in the two consumer files.
Excluded folders (entire sections)β
| Folder | Reason |
|---|---|
docs/05-engineering-guide/ | Internal engineering standards, runbooks, handbook |
docs/contributing-guide/ | Authoring and documentation guidelines |
docs/06-high-level-designs/ | Architecture diagrams and internal design docs |
docs/03-developers/5-convenient-checkout-api/5-customers/ | Internal wallet management operations |
docs/03-developers/5-convenient-checkout-api/8-third-party-integrations/ | 3rd-party integration internals (EIMP events) |
Inline internal sectionsβ
Use the <Audience> component to hide specific sections within a page that merchants should not see:
<Audience include="internal">
This content is only visible in the internal docs build.
</Audience>
<Audience> tag MUST be capitalizedMDX v3 treats lowercase <audience> as a plain HTML element β the browser ignores it and renders the children unconditionally. Only a capitalized <Audience> is processed as a React component.
- β
<Audience include="internal">β correct - β
<audience include="internal">β content always visible to everyone
No import needed β The component is globally registered via src/theme/MDXComponents.js.
4. What to Mark as Internalβ
Must be wrapped in <Audience include="internal">β
| Content type | Examples |
|---|---|
| Infrastructure / architecture details | AKS cluster config, multi-cloud gateway topology, Splunk setup |
| Internal processing flows | Sequence diagrams, wallet merge logic, enterprise settings logic |
| Internal API endpoints or admin APIs | 13--Admin.md, internal-only routes |
| Sensitive error root causes | DB errors, upstream dependencies, internal retry logic |
| Staff-facing notes | Implementation notes, known issues not yet customer-visible |
| Webhook internal mapping | Internal event β external event translation tables |
| HCP-internal URLs | HCP API catalog internal links, internal JIRA/Confluence references |
Does NOT need to be wrappedβ
Leave visible in both builds:
- API request/response schemas
- Integration guides and code examples
- Error codes and resolutions visible to merchants
- Supported payment methods and capabilities
- Customisation and theming docs
- Sandbox/staging credential guidance
5. AI Assistantβ
The AI Assistant (ChatBot + SearchBox) is automatically hidden in the Merchant build. No manual wrapping is needed. This includes:
- The floating ChatBot sidebar (
<ChatBot />inRoot.js) - The AI-powered SearchBox in the Navbar
- The "AI Assistant is available!" announcement bar
6. Checklist Before Publishing a New Pageβ
When adding a doc that will appear in both builds:
- Does the page contain infrastructure or architecture internals? β Wrap in
<Audience include="internal"> - Does it have internal-only processing flows or sequence diagrams? β Wrap in
<Audience include="internal"> - Is it an entire internal-only section? β Add the folder to the
excludelist indocusaurus.config.js - Is the page permission metadata set correctly? (
permission: [merchant, internal, business]) - Run
yarn build:merchantlocally to verify content is stripped correctly