diff --git a/package.json b/package.json
index 226d6f1..05aac28 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
"dev": "astro dev",
"start": "astro dev",
"check": "astro check",
- "build": "astro build",
+ "build": "astro build --force",
"preview": "astro preview",
"astro": "astro",
"format": "prettier --write \"{src,public}/**/*.{astro,css,js,json,mjs,ts}\" \"*.{json,mjs,ts}\"",
diff --git a/src/content/docs/404.mdoc b/src/content/docs/404.mdoc
new file mode 100644
index 0000000..098b107
--- /dev/null
+++ b/src/content/docs/404.mdoc
@@ -0,0 +1,52 @@
+---
+title: Page Not Found
+description: The requested FOSSBilling documentation page could not be found.
+editUrl: false
+lastUpdated: false
+template: splash
+tableOfContents: false
+head:
+ - tag: meta
+ attrs:
+ name: robots
+ content: noindex
+---
+
+The page you are looking for may have moved, been renamed, or no longer exists.
+
+Start with one of the main documentation sections below, or use search to find the topic you need.
+
+{% cardgrid %}
+ {% linkcard
+ title="Getting Started"
+ href="/getting-started/"
+ description="Install FOSSBilling, check requirements, and prepare your environment."
+ /%}
+ {% linkcard
+ title="Maintenance"
+ href="/maintenance/"
+ description="Update, troubleshoot, and maintain an existing FOSSBilling installation."
+ /%}
+ {% linkcard
+ title="Admin Guide"
+ href="/admin-guide/"
+ description="Configure FOSSBilling and manage day-to-day administration tasks."
+ /%}
+ {% linkcard
+ title="Extensions & Development"
+ href="/extensions-and-development/"
+ description="Build modules, themes, payment gateways, and integrations."
+ /%}
+ {% linkcard
+ title="Support"
+ href="/support/"
+ description="Find FAQs, troubleshooting guidance, and community support links."
+ /%}
+ {% linkcard
+ title="GitHub Repository"
+ href="https://github.com/FOSSBilling/FOSSBilling"
+ description="Report issues or browse the FOSSBilling source code."
+ /%}
+{% /cardgrid %}
+
+If you followed a link from the documentation site, please [open an issue](https://github.com/FOSSBilling/docs/issues/new) so it can be corrected.
diff --git a/src/content/docs/admin-guide/company.mdoc b/src/content/docs/admin-guide/company.mdoc
index a1a9e8f..7c5d565 100644
--- a/src/content/docs/admin-guide/company.mdoc
+++ b/src/content/docs/admin-guide/company.mdoc
@@ -20,12 +20,12 @@ Upload the logo assets FOSSBilling should use across the interface:
### Best Practices
-- Store logos in your theme's `assets/` folder
+- Upload custom logos through the settings page so updates do not overwrite them
- Use SVG for crisp display at any size
- Keep file sizes reasonable (< 500KB)
{% aside type="caution" %}
-Don't edit `themes/huraga/assets/img/logo.svg` directly — it's overwritten on updates. Upload your logo through the settings page instead.
+Don't edit the bundled files in `public/branding/` directly. They are default assets and may be overwritten on updates. Upload your logo through the settings page instead.
{% /aside %}
### Logo Not Showing?
diff --git a/src/content/docs/extensions-and-development/file-structure.mdoc b/src/content/docs/extensions-and-development/file-structure.mdoc
index cce05ea..f2c4931 100644
--- a/src/content/docs/extensions-and-development/file-structure.mdoc
+++ b/src/content/docs/extensions-and-development/file-structure.mdoc
@@ -18,6 +18,13 @@ Runtime data storage:
This directory should be writable by the web server.
+### `/src/public`
+
+Public core assets that must be web-accessible:
+- **Assets** — Shared built browser assets (`/public/assets`), including the API wrapper, shared runtime, Markdown CSS, and CKEditor bundle
+- **Branding** — Default logo, dark logo, and favicon (`/public/branding`)
+- **Gateway icons** — Payment gateway logos (`/public/gateways`)
+
### `/src/install`
The installation wizard. Automatically deleted after installation unless `APP_ENV=dev` is set.
@@ -28,7 +35,7 @@ Core PHP classes and business logic.
#### `/src/library/Api`
-Core API files including the JavaScript wrapper (`API.js`). [See the wrapper docs](/extensions-and-development/javascript/).
+Core PHP API files. The browser-side API wrapper source now lives in `/frontend/core/api.js` and builds to `/src/public/assets/js/api.js`. [See the wrapper docs](/extensions-and-development/javascript/).
#### `/src/library/Box`
@@ -87,6 +94,19 @@ These are for shared hosting control panels. For VPS or game servers, consider c
Translations as a Git submodule. Pointing to [github.com/FOSSBilling/locale](https://github.com/FOSSBilling/locale).
+### `/frontend`
+
+Shared frontend source and build tooling:
+
+| Path | Purpose |
+|------|---------|
+| `core/` | Shared browser runtime and API wrapper source |
+| `editor/` | CKEditor integration source |
+| `styles/` | Shared CSS such as Markdown rendering styles |
+| `tools/` | Common esbuild, Sass, PostCSS, asset copy, and PurgeCSS helpers used by theme builds |
+
+The root `npm run build` command builds this directory into `/src/public/assets`.
+
### `/src/modules`
All modules live here. Each module is a self-contained unit of functionality.
@@ -122,6 +142,7 @@ Theme structure:
```
theme-name/
├── assets/ # CSS, JS, images (built via esbuild)
+│ └── build/ # Generated theme assets and manifest
├── config/
│ └── settings.html.twig # Theme settings UI
├── html/ # Twig templates
diff --git a/src/content/docs/extensions-and-development/guides/creating-a-theme.mdoc b/src/content/docs/extensions-and-development/guides/creating-a-theme.mdoc
index 396df50..0805c32 100644
--- a/src/content/docs/extensions-and-development/guides/creating-a-theme.mdoc
+++ b/src/content/docs/extensions-and-development/guides/creating-a-theme.mdoc
@@ -30,7 +30,8 @@ themes/mytheme/
├── assets/ # CSS, JS, images (built via esbuild)
│ ├── css/
│ ├── js/
-│ └── img/
+│ ├── img/
+│ └── build/ # Generated assets and manifest
├── config/
│ └── settings.html.twig # Theme settings UI (optional)
├── html/ # Your templates
@@ -122,10 +123,19 @@ FOSSBilling provides [custom filters](/extensions-and-development/twig-filters)
{{ price | format_currency(currency.code) }} {# Format currency #}
{{ 'client/manage' | url(area: 'admin') }} {# Admin panel link #}
{{ 'css/theme.css' | asset_url }} {# Theme asset URL #}
+{{ 'js/api.js' | public_asset_url }} {# Shared core asset URL #}
{{ date | timeago }} {# "2 hours ago" #}
{{ content | markdown_to_html }} {# Parse Markdown #}
```
+Custom layouts that do not extend the bundled themes should load the shared runtime and API wrapper before theme JavaScript:
+
+```twig
+{{ 'js/fossbilling.js'|public_asset_url|script_tag }}
+{{ 'js/api.js'|public_asset_url|script_tag }}
+
+```
+
## Security Best Practices
- Use `htmlspecialchars` when outputting user data
diff --git a/src/content/docs/extensions-and-development/javascript.mdoc b/src/content/docs/extensions-and-development/javascript.mdoc
index ecc449c..3bda7a8 100644
--- a/src/content/docs/extensions-and-development/javascript.mdoc
+++ b/src/content/docs/extensions-and-development/javascript.mdoc
@@ -19,7 +19,8 @@ If you're building themes or modules, use this wrapper instead of making raw bro
The bundled admin and Huraga themes already load the wrapper. For a custom theme, add this to your base layout before your theme JavaScript:
```twig
-{{ "Api/API.js"|library_url|script_tag }}
+{{ 'js/fossbilling.js'|public_asset_url|script_tag }}
+{{ 'js/api.js'|public_asset_url|script_tag }}
```
diff --git a/src/content/docs/extensions-and-development/twig-filters.mdoc b/src/content/docs/extensions-and-development/twig-filters.mdoc
index 0d91c91..c240270 100644
--- a/src/content/docs/extensions-and-development/twig-filters.mdoc
+++ b/src/content/docs/extensions-and-development/twig-filters.mdoc
@@ -50,7 +50,7 @@ Project-specific filters and functions are defined in these classes:
| Filter | Description |
|--------|-------------|
| `asset_url` | Get the URL for a theme asset. |
-| `library_url` | Get the URL for the library folder. |
+| `public_asset_url` | Get the URL for a shared core public asset built into `/public/assets`. |
| `mod_asset_url` | Get the URL for a module asset. Use the asset path as the filtered value and the module name as the argument. |
| `script_tag` | Generate an HTML `
+{{ 'js/fossbilling.js'|public_asset_url|script_tag }}
+{{ 'js/api.js'|public_asset_url|script_tag }}
-{# API form handled by Api/API.js #}
+{# API form handled by the shared API wrapper #}