diff --git a/app/index.html b/app/index.html
index d811dc9..bb19f87 100644
--- a/app/index.html
+++ b/app/index.html
@@ -952,7 +952,7 @@ body {
// Category state (phase 3)
let categoriesUse = false;
- let categoriesList = []; // [{code, name, direction, message, notfoundmessage, pagenotfoundmessage, font, ...}]
+ let categoriesList = []; // [{code, name, direction, message, notfoundmessage, pagenotfoundmessage, visibilityifnocontent, font, ...}]
let categoriesByCode = {}; // code → category object
let defaultCategoryCode = null;
let activeCategory = null; // current code
@@ -1202,13 +1202,14 @@ body {
// - Home page: always show (per config.homepage or default 'pages/home.md')
// - Variant exists for active category: show
// - Active category has notfoundmessage: show (renderer falls back to default language)
+ // - Active category has visibilityifnocontent: visible: show (renderer shows pagenotfoundmessage)
// - Otherwise: hide
if (!categoriesUse) return true;
if (page.file === defaultPage()) return true;
const variants = page.variants || [];
if (variants.includes(activeCategory)) return true;
const cat = categoriesByCode[activeCategory];
- return !!(cat && cat.notfoundmessage);
+ return !!(cat && (cat.notfoundmessage || cat.visibilityifnocontent === 'visible'));
}
// ─── Theme ────────────────────────────────────────────────
@@ -2243,7 +2244,8 @@ function fmtDatetime(dtStr) {
function visibleCategoryCodesForCurrentPage() {
// Which categories should appear in the dropdown:
// - the variant exists for this page, OR
- // - the category has a notfoundmessage
+ // - the category has a notfoundmessage (fallback to default content), OR
+ // - the category has visibilityifnocontent: visible (shows pagenotfoundmessage instead)
// - always include the active category so user can see what they're on
const out = new Set();
const page = currentPage
@@ -2251,8 +2253,8 @@ function fmtDatetime(dtStr) {
: null;
categoriesList.forEach(cat => {
const hasVariant = !page || !page.variants || page.variants.includes(cat.code);
- const hasMsg = !!cat.notfoundmessage;
- if (hasVariant || hasMsg || cat.code === activeCategory) out.add(cat.code);
+ const alwaysVisible = !!cat.notfoundmessage || cat.visibilityifnocontent === 'visible';
+ if (hasVariant || alwaysVisible || cat.code === activeCategory) out.add(cat.code);
});
return out;
}
diff --git a/docs/reference-config.md b/docs/reference-config.md
index c0b429f..0c0d829 100644
--- a/docs/reference-config.md
+++ b/docs/reference-config.md
@@ -163,6 +163,12 @@ default-category: # The category used when no ?cat= parameter is in
# current page. Also enables fallback: the renderer will fall back to
# the default-category content instead of hiding the page.
# Omit to hide the category from the dropdown when no variant exists.
+ visibilityifnocontent: hidden # hidden (default) or visible.
+ # hidden: category disappears from the selector when no variant exists
+ # for the current page (unless notfoundmessage is also set).
+ # visible: category stays in the selector regardless. When the user
+ # navigates to a page with no variant, pagenotfoundmessage is shown
+ # in the content area. No fallback to default-category content.
pagenotfoundmessage: "This page is not yet available in English."
# Message shown in the content area when a page cannot be fetched for
# this category. Overrides the top-level pagenotfoundmessage.
@@ -204,6 +210,7 @@ categories-selecttext: "Language" # Label shown next to the icon in the categor
| `name-latin` | No | Secondary label in the dropdown, shown alongside `name` when `name` uses a non-Latin script. |
| `direction` | No | `ltr` or `rtl`. Default: `ltr`. RTL flips nav and content direction. |
| `notfoundmessage` | No | Short note shown in the dropdown when no variant exists for the current page. Also enables fallback to default-category content. |
+| `visibilityifnocontent` | No | `hidden` (default) or `visible`. `visible` keeps the category in the selector when no variant exists; navigating to it shows `pagenotfoundmessage` with no fallback to default content. |
| `pagenotfoundmessage` | No | Message shown in the content area when a page cannot be fetched for this category. Overrides the top-level `pagenotfoundmessage`. |
| `font` | No | Font filename from `assets/fonts/`. Loaded on demand when this category is activated. |
| `line-height` | No | Body line height override for this category. Restores to theme default when switching away. |
@@ -277,7 +284,8 @@ categories:
- code: nb
name: Norsk
direction: ltr
- notfoundmessage: "Ikke tilgjengelig på norsk"
+ visibilityifnocontent: visible
+ pagenotfoundmessage: "Denne siden er ikke tilgjengelig på norsk ennå."
- code: ar
name: عربي
name-latin: Arabic