Skip to content

Commit a8a203e

Browse files
NetdocsCopilot
andcommitted
feat(offline): self-host CDN assets by default on production builds
Change optimize.offline to a tri-state (null/true/false). When unset it now self-hosts external assets automatically for production builds (--prod, deploy) while skipping serve/dev for fast local iteration. Explicit true/false still force the behaviour either way. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent c9b0073 commit a8a203e

5 files changed

Lines changed: 30 additions & 11 deletions

File tree

docs-site/docs/setup/building-for-offline-usage.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,34 @@ title: Building for offline usage
55
# Building for offline usage
66

77
Sometimes a site can't be hosted on the web — it ships on a USB stick, lives on an air-gapped
8-
network, or is opened straight from disk with `file://`. By default Netdocs loads a few assets
9-
from CDNs (syntax highlighting, Mermaid, web fonts, emoji). Offline mode **self-hosts all of
10-
them** so the built site is fully self-contained.
8+
network, or is opened straight from disk with `file://`. Netdocs loads a few assets from CDNs
9+
(syntax highlighting, Mermaid, web fonts, emoji) during development; offline mode **self-hosts all
10+
of them** so the built site is fully self-contained. It runs automatically on production builds.
1111

1212
## Enable it
1313

14-
Set `optimize.offline` in `appsettings.json`:
14+
Offline self-hosting is **on by default for production builds**`netdocs build --prod` (and
15+
`deploy`) self-host CDN assets automatically, while `serve`/dev builds skip it so local iteration
16+
stays fast. You don't have to configure anything to get a self-contained published site.
17+
18+
To control it explicitly, set `optimize.offline` in `appsettings.json`:
1519

1620
```json
1721
"optimize": {
1822
"offline": true
1923
}
2024
```
2125

26+
| Value | Behaviour |
27+
|---|---|
28+
| omitted / `null` | **Default.** Self-host on production builds (`--prod`, `deploy`), skip during `serve`. |
29+
| `true` | Always self-host, including local and dev builds. |
30+
| `false` | Never self-host (keep CDN references). |
31+
2232
Then build as usual:
2333

2434
```bash
25-
netdocs build
35+
netdocs build --prod
2636
```
2737

2838
```

src/Netdocs.Abstractions/SiteConfig.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,13 @@ public sealed class OptimizeConfig
205205
/// <c>assets/external/</c>, and rewrites the pages to reference the local copies so the site
206206
/// works without internet (including from <c>file://</c>). Requires network access at build
207207
/// time; assets that fail to download keep their CDN URL and log a warning.
208+
/// <para>
209+
/// Tri-state: <c>null</c> (default) self-hosts on production builds but not during
210+
/// <c>serve</c>/dev, so published sites are resilient while local iteration stays fast and
211+
/// offline. Set <c>true</c> to always self-host, or <c>false</c> to never self-host.
212+
/// </para>
208213
/// </summary>
209-
public bool Offline { get; set; }
214+
public bool? Offline { get; set; }
210215
}
211216

212217
/// <summary>

src/Netdocs.Cli/NewCommand.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,10 @@ public static async Task<int> RunAsync(string[] args)
156156
"minifyJs": false,
157157
"convertImagesToWebp": false,
158158
"webpQuality": 80,
159-
// Self-host every CDN asset (highlight.js, Mermaid, fonts, emoji) so the
160-
// built site runs from file:// — requires network access at build time.
161-
"offline": false
159+
// Self-host every CDN asset (highlight.js, Mermaid, fonts, emoji) so the built
160+
// site runs from file://. Requires network access at build time. Omit for the
161+
// default (self-host on production builds only); set true/false to force it.
162+
"offline": null
162163
},
163164
164165
// --- Build-time validation -------------------------------------------------------

src/Netdocs.Core/BuildEngine.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,9 @@ public async Task<SiteContext> BuildAsync(CancellationToken ct = default)
224224
}
225225

226226
// 13b. Offline self-hosting: download external CDN assets and rewrite pages to local copies.
227-
if (config.Optimize.Offline)
227+
// Tri-state: null => self-host on production builds only (not serve/dev); true/false forces it.
228+
var offline = config.Optimize.Offline ?? (options.IsProduction && !options.IsServe);
229+
if (offline)
228230
using (Measure("13b. self-host assets"))
229231
await Optimization.SelfHostAssets.RunAsync(site, _log, ct);
230232

src/Netdocs.Core/Configuration/JsonConfigLoader.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ public static SiteConfig Load(string appSettingsPath)
7676
MinifyJs = m.Get("minifyJs").AsBool(false),
7777
ConvertImagesToWebp = m.Get("convertImagesToWebp").AsBool(false),
7878
WebpQuality = m.Get("webpQuality").AsInt(80),
79-
Offline = m.Get("offline").AsBool(false),
79+
// Tri-state: absent => null (auto: production-only). Present => explicit true/false.
80+
Offline = m.Get("offline") is { } off ? off.AsBool(false) : null,
8081
};
8182

8283
private static SlugifyConfig ParseSlugify(IReadOnlyDictionary<string, object?> m) => new()

0 commit comments

Comments
 (0)