This is the official website for Datum Inc., built with Astro.
- Getting Started
- Development Environment
- Content Authoring
- API Documentation
- Code Quality & Testing
- Production Deployment
- Third-party Integrations
- Contributing
- Resources
- Node.js 24.15+ (matches the version pinned in
Dockerfile)
- Install dependencies:
npm install- Set up environment variables:
cp .env.example .env
# Edit .env with your configuration- Start the development server:
npm run devFor detailed information about the project structure, see PROJECT_STRUCTURE.md.
All commands are run from the root of the project, from a terminal:
| Command | Action |
|---|---|
npm install |
Installs dependencies |
npm run dev |
Starts local dev server at localhost:4321 |
npm run build |
Build your production site to ./dist/ |
npm run build:cache |
Warm up the Strapi cache (see docs/STRAPI_CACHE_API.md) |
npm run preview |
Preview your build locally, before deploying |
npm run start |
Run the production Node server entry (./server.mjs) |
npm run astro ... |
Run CLI commands like astro add, astro check |
npm run astro -- --help |
Get help using the Astro CLI |
npm run lint |
Check for linting and formatting issues |
npm run lint:fix |
Automatically fix linting and formatting issues |
npm run lint:md |
Check for markdown linting issues |
npm run lint:md:fix |
Automatically fix markdown linting issues |
npm run format |
Format all files using Prettier |
npm run format:check |
Check if files are formatted correctly |
npm run typecheck |
Astro typescript check |
npm run precommit |
Typecheck, ESLint, and markdown lint (Husky formats/lints staged files on commit) |
npm run test:e2e |
Run Playwright E2E tests in headless mode |
- Docker
- Docker Compose
-
Set up environment variables:
cp .env.example .env
Edit
.envwith your configuration. -
Start the development environment:
docker compose up dev
This will:
- Build the development image using Node.js 24.15 Alpine (see
Dockerfile) - Mount your local codebase for hot-reloading
- Make the app available at http://localhost:4321
- Build the development image using Node.js 24.15 Alpine (see
-
Development Features:
- Hot-reloading enabled
- Source code mounted from host
- Node modules cached in Docker volume
- Full access to development tools
- Network access from other devices via host IP
- Install Minikube and start minikube:
minikube start- Create
secret.yamlwith the data keys required by the deployment. See.env.examplefor the full list of environment variables the app expects (OIDC, Strapi, Postgres, GitHub App credentials, etc.). Minimum baseline shown below — extend with whatever your local deployment needs:
apiVersion: v1
kind: Secret
metadata:
name: datum-net
namespace: datum-net
type: Opaque
data:
POSTGRES_USER:
POSTGRES_PASSWORD:
APP_ID:
APP_INSTALLATION_ID:
APP_PRIVATE_KEY:
# Add additional keys from .env.example as needed- Then apply with command:
Create namespace:
kubectl create namespace datum-netApply secret:
kubectl apply -f config/dev/secret.yamlApply the kustomize config file:
kubectl apply -k config/baseApply the kustomize postgres config file:
kubectl apply -k config/dev/postgres-config.yaml- Install postgresql helm (example from bitnami source):
helm install postgresql -f config/dev/postgres-values.yaml -n datum-net oci://registry-1.docker.io/bitnamicharts/postgresqlMain file: src/content/handbook/index.md
Import component:
import Figure from '@components/Figure.astro';Example in real use: src/content/blog/from-cage-nuts-to-kubernetes.mdx
<Figure title="Caption text" align="left/center/right">  </Figure>Align left:
Align center:
Align right:
This project uses Front Matter CMS - a powerful headless CMS that runs directly in VS Code, providing a GUI for managing your Astro content collections.
- Open VS Code
- Go to Extensions (⌘+Shift+X on Mac, Ctrl+Shift+X on Windows/Linux)
- Search for "Front Matter CMS"
- Click "Install" on the extension by Elio Struyf
Note: If the repo includes a .frontmatter/ configuration, you can use it and skip manual Front Matter project initialization.
| Content Type | Description | Location |
|---|---|---|
docs |
Documentation pages | src/content/docs/ |
blog |
Blog posts | src/content/blog/ |
authors |
Author profiles | src/content/authors/ |
handbook |
Company handbook | src/content/handbook/ |
changelog |
Version changelogs | src/content/changelog/ |
features |
Product features | src/content/features/ |
faq |
FAQ entries | src/content/faq/ |
categories |
Blog categories | src/content/categories/ |
pages |
Marketing pages | src/content/pages/ |
about |
About pages | src/content/about/ |
legal |
Legal documents | src/content/legal/ |
careers |
Open roles / careers | src/content/careers/ |
events |
Events | src/content/events/ |
pricing |
Pricing copy | src/content/pricing/ |
download |
Download landing copy | src/content/download/ |
The project uses reusable field groups for complex structures:
| Field Group | Used In | Purpose |
|---|---|---|
og |
Meta fields | Open Graph social sharing data |
hero |
Docs, handbook | Hero section with tagline and image |
social |
Authors | Social media links (Twitter, GitHub, LinkedIn) |
price |
Pricing | Price structure (badge, amount, note) |
cta |
Pricing, pages | Call-to-action buttons |
images |
Pages, about | Image galleries with alt text |
readTheDocs |
Features | Documentation links |
changelogTags |
Changelog | Tag entries (fixed/new/changed) |
If the Front Matter panel is not showing:
- Ensure you have a content file open
- Check the file is in
src/content/directory - Try reloading VS Code:
Developer: Reload Window
⚠️ Currently disabled. Thenpm run generate:api-docsscript is no longer present inpackage.jsonand the previously generatedsrc/content/docs/docs/api/reference.mdxis not in the tree. The pipeline below describes the historical setup and is kept for reference until it is either restored or formally retired. File an issue if you need API reference docs regenerated.
The API reference documentation is auto-generated from the CRD (Custom Resource Definition) source code in the operator repositories.
- Go (version 1.20+)
- Node.js (version 18+)
- curl, unzip (for downloading source archives)
To regenerate the API reference documentation:
npm run generate:api-docsThis single command:
- Cleans any previous temporary files
- Installs the crd-ref-docs tool (if needed)
- Downloads the configured operator repositories
- Extracts CRD definitions from Go source code
- Generates MDX documentation using templates
- Outputs to
src/content/docs/docs/api/reference.mdx
Temporary files are automatically cleaned up at the start of each run.
API documentation generation is configured in:
.api-docs-config.yaml- Source repository versions and settings.crd-ref-docs.yaml- CRD documentation tool configurationtemplates/api-docs/- MDX templates for documentation rendering
Renovate automatically:
- Tracks operator releases
- Detects new versions from GitHub releases
- Creates a weekly PR (before 3am Monday) with:
- Updated versions in
.api-docs-config.yaml - All operators grouped in a single PR
- Updated versions in
A GitHub Actions workflow automatically regenerates the API documentation when Renovate opens a PR that modifies .api-docs-config.yaml, committing the updated docs to the same PR.
For manual updates, edit version numbers in .api-docs-config.yaml and run npm run generate:api-docs.
This project uses ESLint with Prettier integration for code quality and formatting:
- ESLint: For code linting and enforcing code style rules
- Prettier: Integrated with ESLint for code formatting
- TypeScript: For type checking and enhanced IDE support
- Markdownlint: For markdown and MDX file linting
The configuration supports:
- TypeScript (
.ts,.tsx) - JavaScript (
.js,.jsx) - Astro (
.astro) - Markdown (
.md) - MDX (
.mdx) - JSON (
.json)
The project uses markdownlint-cli to ensure consistent markdown formatting across all content files. The linting is specifically configured for MDX files with React components in the /src/content/ directory.
The markdownlint configuration (.markdownlint.json) is optimized for MDX and React components:
- Disables line length limits (MD013)
- Allows inline HTML/JSX (MD033)
- Flexible heading structure (MD024, MD025, MD026)
- Supports component-based content (MD036, MD040)
- Allows dynamic content (MD042, MD047)
- Flexible list formatting (MD029, MD031, MD032)
To check markdown files:
npm run lint:mdTo automatically fix markdown issues:
npm run lint:md:fixThe linter will only check files in the /src/content/ directory, including:
- Blog posts
- Documentation
- Guides
- Changelog entries
- Static pages
For the best development experience, install the following VS Code extensions:
- ESLint
- Prettier
- Markdownlint
- Front Matter CMS - For content management
The project includes VS Code settings (.vscode/settings.json) that enable:
- Live linting and error detection
- Format on save
- Automatic ESLint fixes on save
- Proper formatting for Astro, TypeScript, JavaScript, and Markdown files
- TypeScript SDK integration
This project uses Playwright for end-to-end testing, providing reliable testing across multiple browsers.
- Install dependencies:
npm install- Install Playwright browsers:
npx playwright install| Command | Action |
|---|---|
npm run test:e2e |
Run all tests in headless mode |
npm run test:e2e:ui |
Run tests with UI mode (recommended for dev) |
npm run test:e2e:debug |
Run tests in debug mode |
npm run test:e2e:report |
Show the last test report |
Tests are located in the tests/e2e directory:
tests/
└── e2e/
├── home.spec.ts # Homepage tests
└── ... # Other test files
- Test reports are generated in the
playwright-reportdirectory - Screenshots and videos of failures are saved in
test-results - Reports are not committed to the repository (see
.gitignore)
Example test structure:
import { test, expect } from '@playwright/test';
test.describe('Feature Name', () => {
test('should do something specific', async ({ page }) => {
await page.goto('/');
// Test implementation
});
});The tests are configured to run in CI environments:
- Retries failed tests in CI
- Generates HTML reports
- Takes screenshots on failures
- Supports parallel test execution
The project includes configuration files to ignore certain files and directories:
.prettierignore: Specifies files and directories to be ignored by Prettier.eslintignore: Specifies files and directories to be ignored by ESLint
These files ignore:
- Build output (
dist/,.astro/) - Dependencies (
node_modules/) - Generated files (
*.generated.*,*.min.*) - Log files
- Environment files (except
.env.example) - Editor directories and files
- Package manager files
- Public assets
-
Build and run the production environment:
docker compose up prod
This will:
- Build an optimized production image
- Run the application in production mode
- Enable automatic restarts unless stopped
- Make the app available at http://localhost:4321
-
Manual production deployment:
# Build the production image docker build -t datum-website --target production . # Run the production container docker run -p 4321:4321 \ -e NODE_ENV=production \ -e SITE_URL=your-site-url \ datum-website
The setup uses a multi-stage Dockerfile:
-
Base stage (
node:24.15.0-alpine3.22)- Minimal Alpine Linux with Node.js 24.15
- Common workspace setup
-
Development stage
- Full development dependencies
- Source code mounting
- Hot-reload enabled
- Development-specific configurations
-
Production stage
- Multi-stage build for optimization
- Only production dependencies
- Pre-built assets
- Minimal final image size
- Host:
0.0.0.0(allows external access) - Port: 4321 (configurable via environment)
- Docker network:
datum-network(bridge mode) - Volume mounts (development):
.:/src: Source code/app/node_modules: Dependencies
-
If the development server isn't accessible:
# Rebuild the development image docker compose up dev --build -
To view logs:
# Development logs docker compose logs dev # Production logs docker compose logs prod
-
To clean up:
# Stop and remove containers docker compose down # Remove volumes too docker compose down -v
All browser-side third-party scripts are loaded from
src/components/LayoutEmbedScripts.astro.
Most are gated to production (NODE_ENV=production) so they do not run during
npm run dev or local preview without the flag set.
| Service | Purpose | Loader file | Production-only |
|---|---|---|---|
| Fathom | Privacy-friendly analytics + event tracking | LayoutEmbedScripts.astro |
No |
| HelpScout | Live chat / customer support widget | LayoutEmbedScripts.astro |
Yes |
| Hyperping | Status badge on the site footer | LayoutEmbedScripts.astro |
No |
| Marker.io | In-page bug / feedback capture | public/scripts/markerio.js |
Yes |
| MaxMind | Device fingerprint for signup fraud signal | LayoutEmbedScripts.astro |
Yes |
| WebMCP | Exposes site tools to AI agents via WebMCP | LayoutEmbedScripts.astro |
No |
- Beacon ID is configured in
LayoutEmbedScripts.astro. - Any
<a>(or other element) withclass="open-beacon"will open the Beacon widget when clicked.
Production-gated widgets do not load on npm run dev. Two ways to verify:
# Full prod simulation (build then preview)
npm run build
NODE_ENV=production npm run previewor temporarily flip the if (!isProduction) return; guard in
LayoutEmbedScripts.astro for the widget you are testing (remember to revert
before committing).
We welcome contributions! Please see our Contributing Guide for details on our code of conduct, development setup, and the process for submitting pull requests.