Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
/out/
/build
*.tsbuildinfo
/.wrangler/

# misc
.DS_Store
Expand All @@ -24,3 +25,12 @@ yarn-error.log*
.env*.local
.vercel
next-env.d.ts

# doc images -- served from R2 (see worker/index.ts), not committed here.
# Fine to drop a file here temporarily for a `next dev` preview; it just
# won't be tracked, and scripts/nest-static-export.mjs strips it from any
# build output before deploy either way.
/public/img/

# holds a real Cloudflare API token -- see scripts/README.md
/scripts/.env.publish-image
29 changes: 19 additions & 10 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ This site follows the same Cloudflare Workers static-assets pattern used by the

- **Next.js static export** - `next build` outputs static files to `out/`
- **Next.js `basePath`** - links and assets are generated under `/docs/atom`
- **Post-build nesting** - `scripts/nest-static-export.mjs` moves the export under `out/docs/atom/` so Cloudflare static assets can serve it from the route prefix without custom Worker code
- **Post-build nesting** - `scripts/nest-static-export.mjs` moves the export under `out/docs/atom/` so Cloudflare static assets can serve it from the route prefix
- **Doc images via R2** - `worker/index.ts` is a small Worker in front of the static assets that serves `/docs/atom/img/...` from a shared Cloudflare R2 bucket instead of the repo, so images can be updated and cache-purged without a rebuild. It only runs as a fallback for requests that don't match a static asset (`run_worker_first: false`, the default) - every actual page is still served directly from `out/` with no Worker involved. See [`scripts/README.md`](./scripts/README.md) for the full picture and the publishing workflow.

### Cloudflare Build Settings

Expand Down Expand Up @@ -57,9 +58,14 @@ flowchart LR
end

subgraph Runtime_Request_Flow
U[Browser request] --> H[Cloudflare static asset route]
H --> J[Static asset lookup]
U[Browser request] --> H{Matches a static asset?}
H -->|yes| J[Serve from out/]
J --> U
H -->|no, e.g. /docs/atom/img/...| K[worker/index.ts]
K -->|img path| L[R2: websites-images/atom-docs/...]
K -->|anything else| M[404 via assets binding]
L --> U
M --> U
end
```

Expand All @@ -73,10 +79,13 @@ NEXT_PUBLIC_BASE_URL=https://www.absmach.eu/docs/atom

## Project Structure

| Path | Description |
| -------------------------------- | --------------------------------------- |
| `app/[[...slug]]/page.tsx` | Docs page renderer |
| `content/docs` | MDX source files |
| `lib/source.ts` | Fumadocs source adapter |
| `scripts/nest-static-export.mjs` | Moves static export under `/docs/atom` |
| `wrangler.jsonc` | Cloudflare Workers static-assets config |
| Path | Description |
| ---------------------------------- | -------------------------------------------------------------------------------- |
| `app/[[...slug]]/page.tsx` | Docs page renderer |
| `content/docs` | MDX source files |
| `lib/source.ts` | Fumadocs source adapter |
| `components/doc-image.tsx` | Renders doc images as a plain, zoomable `<img>` (no `next/image`, no manifest) |
| `worker/index.ts` | Serves `/docs/atom/img/...` from R2, falls back to static assets otherwise |
| `scripts/nest-static-export.mjs` | Moves static export under `/docs/atom`, strips any local `img/` from it |
| `scripts/publish-image.mjs` | Maintainer-only: uploads a doc image to R2 and purges its cache |
| `wrangler.jsonc` | Cloudflare Workers static-assets + Worker + R2 binding config |
5 changes: 5 additions & 0 deletions docs/app/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Callout } from 'fumadocs-ui/components/callout';
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
import type { Metadata } from 'next';
import { Mermaid } from '@/components/mermaid';
import { DocImage } from '@/components/doc-image';

const mdxComponents = {
...defaultMdxComponents,
Expand All @@ -24,6 +25,10 @@ const mdxComponents = {
Mermaid,
Tab,
Tabs,
// Overrides defaultMdxComponents' next/image-backed img -- doc images are
// served from R2 via a same-origin proxy, not bundled by next/image. See
// components/doc-image.tsx.
img: DocImage,
};

export default async function Page({
Expand Down
39 changes: 39 additions & 0 deletions docs/components/doc-image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { ImageZoom } from "fumadocs-ui/components/image-zoom";
import type { ImgHTMLAttributes } from "react";

// Doc content images (content/docs/**/*.mdx) are no longer bundled by
// Next.js's image pipeline (see source.config.ts: remarkImageOptions is
// disabled). They're stored in the shared Cloudflare R2 bucket and served
// same-origin at their usual "/img/..." path -- see docs/wrangler.jsonc and
// worker/index.ts. Rendered as a plain, zoomable <img> -- no next/image, no
// width/height needed, so there's nothing to keep in sync when images
// change.
const BASE_PATH = process.env.NEXT_PUBLIC_BASE_PATH ?? "";

export function DocImage({
src,
alt,
className,
...props
}: ImgHTMLAttributes<HTMLImageElement>) {
if (typeof src !== "string") return null;

const resolvedSrc = src.startsWith("/") ? `${BASE_PATH}${src}` : src;

return (
// src/alt passed here too, not just to the inner <img>: ImageZoom's
// zoomed-in view reads its image from these props directly, not from
// `children` -- omitting them renders a blank zoomed-in image even
// though the inline thumbnail (via children) looks correct.
<ImageZoom src={resolvedSrc} alt={alt ?? ""}>
{/* biome-ignore lint/performance/noImgElement: doc content images are served from R2, not Next's image pipeline */}
<img
{...props}
src={resolvedSrc}
alt={alt ?? ""}
loading="lazy"
className={["rounded-lg", className].filter(Boolean).join(" ")}
/>
</ImageZoom>
);
}
4 changes: 4 additions & 0 deletions docs/mdx-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Callout } from 'fumadocs-ui/components/callout';
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
import type { MDXComponents } from 'mdx/types';
import { Mermaid } from './components/mermaid';
import { DocImage } from './components/doc-image';

export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
Expand All @@ -17,6 +18,9 @@ export function useMDXComponents(components: MDXComponents): MDXComponents {
Mermaid,
Tab,
Tabs,
// Overrides defaultComponents' next/image-backed img -- see
// components/doc-image.tsx for why.
img: DocImage,
...components,
};
}
17 changes: 14 additions & 3 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
"dev": "next dev --turbopack",
"build": "next build && node scripts/nest-static-export.mjs",
"start": "serve out",
"deploy": "pnpm run build && wrangler deploy",
"upload": "pnpm run build && wrangler versions upload"
"typecheck:worker": "tsc --noEmit -p worker/tsconfig.json",
"deploy": "pnpm run build && pnpm run typecheck:worker && wrangler deploy",
"upload": "pnpm run build && pnpm run typecheck:worker && wrangler versions upload",
"preview": "pnpm run build && wrangler dev",
"publish-image": "node scripts/publish-image.mjs"
},
"dependencies": {
"@orama/orama": "^3.1.18",
Expand All @@ -21,6 +24,7 @@
"react-dom": "^19"
},
"devDependencies": {
"@cloudflare/workers-types": "^4",
"@types/mdx": "^2.0.13",
"@types/node": "^22",
"@types/react": "^19",
Expand All @@ -32,5 +36,12 @@
"typescript": "^5",
"wrangler": "^4.95.0"
},
"packageManager": "pnpm@10.33.0"
"packageManager": "pnpm@10.33.0",
"pnpm": {
"overrides": {
"js-yaml": "^4.3.1",
"sharp": "^0.35.3",
"postcss": "^8.5.18"
}
}
}
40 changes: 24 additions & 16 deletions docs/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed docs/public/img/user-guide/account/account-menu.png
Binary file not shown.
Binary file removed docs/public/img/user-guide/account/profile-page.png
Binary file not shown.
Binary file removed docs/public/img/user-guide/account/theme-menu.png
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed docs/public/img/user-guide/actions/actions-list.png
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed docs/public/img/user-guide/audit/audit-inspect.png
Binary file not shown.
Binary file removed docs/public/img/user-guide/audit/audit-list.png
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Binary file removed docs/public/img/user-guide/developer/playground.png
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Binary file removed docs/public/img/user-guide/roles/role-inspect.png
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
10 changes: 10 additions & 0 deletions docs/scripts/.env.publish-image.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copy to scripts/.env.publish-image (gitignored) and fill in the token.
# Create the token under My Profile -> API Tokens -> Create Token -> Custom Token, with:
# - Workers R2 Storage: Edit
# - Zone -> Cache Purge -> Purge (scoped to the absmach.eu zone)
CLOUDFLARE_API_TOKEN=

# Not secret - the absmach.eu zone ID, visible on the domain's Overview page.
# Same zone as the main absmach-website repo (this docs site is served at
# https://www.absmach.eu/docs/atom, same domain).
CLOUDFLARE_ZONE_ID=9cb2232dc0e21fbfabf9ce52b1834f56
Loading
Loading