diff --git a/_scripts/add-index-html-links.sh b/_scripts/add-index-html-links.sh
new file mode 100644
index 00000000000..64da55347ff
--- /dev/null
+++ b/_scripts/add-index-html-links.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+# Post-processing script for Siemens internal deployment.
+# Rewrites directory-style href links (ending with /) to explicit /index.html
+# links in all HTML files under public/, so the Siemens server can serve them
+# without requiring automatic directory index support.
+#
+# When built with the siemens-internal environment, canonifyURLs=true causes Hugo
+# to expand all internal links to full absolute URLs using the baseURL. Pass that
+# baseURL as the second argument so those links are rewritten too.
+#
+# Rewrites both plain directory links and directory links with anchors:
+# href=".../path/" → href=".../path/index.html"
+# href=".../path/#anchor" → href=".../path/index.html#anchor"
+#
+# Skips:
+# - External links (contain :// but do not start with base-url)
+# - Anchor-only links starting with #
+# - Links already containing index.html or ending in .html/.htm
+#
+# Usage: bash _scripts/add-index-html-links.sh [public-dir] [base-url]
+# Default public-dir: public
+# Default base-url: (empty — only root-relative and relative links are rewritten)
+#
+# Example (siemens-internal build):
+# bash _scripts/add-index-html-links.sh public \
+# https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/
+
+set -euo pipefail
+
+PUBLIC_DIR="${1:-public}"
+BASE_URL="${2:-}"
+
+if [ ! -d "$PUBLIC_DIR" ]; then
+ echo "Error: directory '$PUBLIC_DIR' not found. Run hugo build first." >&2
+ exit 1
+fi
+
+echo "Adding index.html to directory links in $PUBLIC_DIR..."
+[ -n "$BASE_URL" ] && echo "Treating '$BASE_URL' as internal base URL."
+
+python3 - "$PUBLIC_DIR" "$BASE_URL" << 'PYTHON'
+import re, sys
+from pathlib import Path
+
+public_dir = sys.argv[1]
+base_url = sys.argv[2].rstrip("/") + "/" if sys.argv[2] else ""
+
+HREF_RE = re.compile(r"""(href=["'])([^"']*)(["'])""")
+
+def rewrite_href(m):
+ pre, url, quote = m.group(1), m.group(2), m.group(3)
+
+ # Treat absolute URLs that start with base_url as internal; skip all others
+ if "://" in url:
+ if not (base_url and url.startswith(base_url)):
+ return m.group(0)
+
+ # Skip anchor-only links
+ if url.startswith("#"):
+ return m.group(0)
+
+ # Split off any fragment (e.g. /path/#anchor → path=/path/, fragment=#anchor)
+ fragment = ""
+ if "#" in url:
+ url, fragment = url.split("#", 1)
+ fragment = "#" + fragment
+
+ # Skip already-explicit file links
+ if url.endswith(".html") or url.endswith(".htm"):
+ return f"{pre}{url}{fragment}{quote}"
+
+ if url.endswith("/"):
+ url = url + "index.html"
+ return f"{pre}{url}{fragment}{quote}"
+
+count = 0
+for path in Path(public_dir).rglob("*.html"):
+ original = path.read_text(encoding="utf-8", errors="replace")
+ updated = HREF_RE.sub(rewrite_href, original)
+ if updated != original:
+ path.write_text(updated, encoding="utf-8")
+ count += 1
+
+print(f"Updated {count} HTML files.")
+PYTHON
diff --git a/_scripts/fix-siemens-paths.sh b/_scripts/fix-siemens-paths.sh
new file mode 100644
index 00000000000..42673ae6d59
--- /dev/null
+++ b/_scripts/fix-siemens-paths.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Post-processing script for Siemens internal deployment
+# NOTE: As of Hugo v0.156.0, the doubled-path bug has been fixed.
+# This script is kept for backwards compatibility but no longer performs any actions.
+
+echo "Siemens internal deployment post-processing..."
+echo "✓ Hugo v0.156.0+ correctly handles deep baseURL paths"
+echo "✓ No file copying needed - all asset references are correct"
+echo "Done!"
diff --git a/assets/scss/_font-face.scss b/assets/scss/_font-face.scss
index db27cd448a2..afe1020d3d4 100644
--- a/assets/scss/_font-face.scss
+++ b/assets/scss/_font-face.scss
@@ -1,35 +1,35 @@
@font-face { // LZ - Added for MxDock by request 2024-01-30
font-family: "noto-sans";
- src: local("noto-sans"), url("/fonts/noto-sans/noto-sans-400.woff2") format("woff2");
+ src: local("noto-sans"), url("../fonts/noto-sans/noto-sans-400.woff2") format("woff2");
font-style: normal;
font-weight: 400;
font-display: swap;
}
-
+
@font-face {
font-family: "noto-sans";
- src: local("noto-sans"), url("/fonts/noto-sans/noto-sans-400-italic.woff2") format("woff2");
+ src: local("noto-sans"), url("../fonts/noto-sans/noto-sans-400-italic.woff2") format("woff2");
font-style: italic;
font-weight: 400;
font-display: swap;
}
-
+
@font-face {
font-family: "noto-sans";
- src: local("noto-sans"), url("/fonts/noto-sans/noto-sans-600.woff2") format("woff2");
+ src: local("noto-sans"), url("../fonts/noto-sans/noto-sans-600.woff2") format("woff2");
font-style: normal;
font-weight: 600;
font-display: swap;
}
-
+
@font-face {
font-family: "noto-sans";
- src: local("noto-sans"), url("/fonts/noto-sans/noto-sans-600-italic.woff2") format("woff2");
+ src: local("noto-sans"), url("../fonts/noto-sans/noto-sans-600-italic.woff2") format("woff2");
font-style: italic;
font-weight: 600;
font-display: swap;
}
-
+
/* Medium */
@font-face {
font-family: "Patron";
@@ -37,9 +37,9 @@
font-weight: 500;
font-display: swap;
src: local("Patron Medium"), local("Patron-Medium"),
- url("/fonts/patron/PatronWEB-Medium.woff2") format("woff2");
+ url("../fonts/patron/PatronWEB-Medium.woff2") format("woff2");
}
-
+
/* Light */
@font-face {
font-family: "Patron";
@@ -47,7 +47,7 @@
font-weight: 300;
font-display: swap;
src: local("Patron Light"), local("Patron-Light"),
- url("/fonts/patron/PatronWEB-Light.woff2") format("woff2");
+ url("../fonts/patron/PatronWEB-Light.woff2") format("woff2");
}
/* The main font is Noto Sans */
diff --git a/config/siemens-internal/INDEX-HTML-WORKAROUND.md b/config/siemens-internal/INDEX-HTML-WORKAROUND.md
new file mode 100644
index 00000000000..42263ef3ac5
--- /dev/null
+++ b/config/siemens-internal/INDEX-HTML-WORKAROUND.md
@@ -0,0 +1,157 @@
+# Adding index.html to Directory Links for Siemens Deployment
+
+## The Problem
+
+The Siemens internal web server does not automatically serve `index.html` when a directory URL is requested. When a user or browser requests `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/refguide/`, the server does not automatically serve the `refguide/index.html` file.
+
+Hugo's `uglyURLs = true` setting helps by making URLs explicit where possible, but Hugo still generates many directory-style links (ending with `/`) throughout the site, particularly in:
+
+* Navigation menus
+* Breadcrumbs
+* Internal page links
+* Table of contents
+
+## Recommended Solution: Post-Processing
+
+The cleanest approach is to post-process the HTML files after Hugo builds them, rewriting directory links to explicitly include `/index.html`.
+
+### How It Works
+
+1. **Hugo builds the site normally** using the siemens-internal environment
+2. **Post-processing script runs** and:
+ * Scans all HTML files in the `public/` directory
+ * Identifies internal links that end with `/` (directory links)
+ * Rewrites them to end with `/index.html`
+ * Preserves external links, anchor links, and explicit file references unchanged
+
+3. **Resulting HTML has explicit paths** that the Siemens server can serve correctly
+
+### Link Transformation Examples
+
+**Navigation links:**
+
+```html
+
+
+
+
+
+```
+
+**Breadcrumb links:**
+
+```html
+
+
+
+
+
+```
+
+### What Gets Changed
+
+✅ **Internal directory links**: `href=".../"` → `href=".../index.html"`
+✅ **Internal directory links with anchors**: `href=".../#section"` → `href=".../index.html#section"`
+
+❌ **External links**: `href="https://example.com/..."` (unchanged)
+❌ **Anchor-only links**: `href="#section"` (unchanged)
+❌ **File links**: `href=".../page.html"` (unchanged)
+❌ **Protocol links**: `href="mailto:..."`, `href="javascript:..."` (unchanged)
+
+### Implementation Approach
+
+The post-processing can be implemented using standard text processing tools:
+
+**Option 1: Using sed (bash)**
+
+* Fast and simple for straightforward pattern matching
+* May require careful escaping of special characters
+* Best for simple, well-defined patterns
+
+**Option 2: Using a scripting language (Python/Node.js)**
+
+* More reliable HTML parsing
+* Better handling of edge cases
+* Can use proper HTML parsers (BeautifulSoup, cheerio, etc.)
+* More maintainable for complex transformations
+
+**Option 3: Using specialized tools (htmlq, pup)**
+
+* Purpose-built for HTML manipulation
+* Balance between sed simplicity and full scripting power
+
+### Integration with Build Process
+
+Update the build workflow to:
+
+```bash
+# Build the site
+hugo --environment siemens-internal --cleanDestinationDir
+
+# Post-process to add index.html to directory links
+bash _scripts/add-index-html-links.sh public \
+ https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/
+```
+
+The script is kept in `_scripts/` alongside the existing (now no-op) `fix-siemens-paths.sh`.
+
+### Advantages
+
+* ✅ **Non-invasive**: Does not require modifying Hugo templates or Docsy theme files
+* ✅ **Environment-specific**: Only affects siemens-internal builds
+* ✅ **Maintainable**: Clear separation between Hugo build and Siemens-specific processing
+* ✅ **Reversible**: Disable by skipping the post-processing step
+* ✅ **Hugo-version independent**: Works regardless of Hugo updates
+* ✅ **Preserves other outputs**: Standard HTML and print versions remain unchanged
+
+### Disadvantages
+
+* ❌ **Build-time overhead**: Adds processing time (likely 5-30 seconds depending on implementation)
+* ❌ **Two-step process**: Requires running a script after Hugo build
+* ❌ **Pattern matching complexity**: Must identify which links to transform precisely
+
+## Alternative Solution: Hugo Render Hooks and Custom Layouts
+
+Instead of post-processing, modify Hugo's rendering behavior at build time.
+
+### How It Works
+
+1. **Create custom render hooks** for Markdown links in `.layouts/_default/_markup/`
+2. **Override navigation partials** from Docsy theme to append `/index.html`
+3. **Configure hooks** to only apply for siemens-internal environment
+
+### Required Changes
+
+* Copy Docsy navigation partial files to local `layouts/` directory
+* Modify link generation logic to append `/index.html` to directory URLs
+* Create Markdown render hooks for content links
+* Add conditional logic to check environment
+
+### Advantages
+
+* ✅ **Build-time only**: No post-processing step required
+* ✅ **Single build command**: Just run `hugo --environment siemens-internal`
+
+### Disadvantages
+
+* ❌ **More invasive**: Requires copying and modifying theme files
+* ❌ **Maintenance burden**: Must update custom layouts when Docsy updates
+* ❌ **Complexity**: Multiple layout files need modification
+* ❌ **Testing required**: Must verify all link types work correctly
+* ❌ **Harder to isolate**: Siemens-specific logic mixed with layout code
+
+## Recommendation
+
+Use the **post-processing approach** because:
+
+1. Hugo v0.156.0 already eliminated the need for the previous doubled-path workaround, and the post-processing approach proved straightforward to implement
+2. The script can be kept simple and focused on one task
+3. It does not require maintaining customized Docsy theme files
+4. It is easier to test, debug, and modify
+5. It keeps the Siemens-specific logic isolated and well-documented
+
+The slight increase in build time is acceptable for a deployment that happens infrequently, and the maintainability benefits outweigh the minor inconvenience of a two-step build process.
+
+## Status
+
+This solution has been implemented. The script is at `_scripts/add-index-html-links.sh` and the build steps are documented in `config/siemens-internal/README.md`.
diff --git a/config/siemens-internal/README.md b/config/siemens-internal/README.md
new file mode 100644
index 00000000000..4a8bb409b64
--- /dev/null
+++ b/config/siemens-internal/README.md
@@ -0,0 +1,114 @@
+# Siemens Internal Deployment Configuration
+
+This directory contains the Hugo environment configuration for deploying the Mendix documentation to the Siemens internal documentation portal.
+
+## Deployment URL
+
+The site is deployed at:
+
+```
+https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/
+```
+
+## The Problems
+
+### 1. Deep URL Path (Fixed in Hugo v0.156.0+)
+
+**Historical Issue**: Earlier versions of Hugo had a bug where `canonifyURLs` generated doubled paths for CSS and JS assets when deploying to a deep URL path (not at the domain root).
+
+Example of the old bug:
+
+* Expected: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/scss/main.css`
+* Generated: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/documentation/internal/PL20260323299104942/en-US/public/scss/main.css`
+
+**Status**: ✅ This issue was fixed in Hugo v0.156.0. The `canonifyURLs` setting now correctly handles deep baseURL paths without generating doubled paths.
+
+### 2. Pretty URLs Not Supported
+
+The Siemens internal server does not serve Hugo's default "pretty URLs" (like `/page/` resolving to `/page/index.html`). `uglyURLs = true` helps, but Hugo still generates many directory-style links (ending with `/`) in navigation menus, breadcrumbs, and table-of-contents entries.
+
+A post-processing script rewrites all remaining directory-style `href` links to include `/index.html` explicitly.
+
+## The Solution
+
+Configure Hugo with the appropriate settings for deep URL deployment, then run the post-processing script:
+
+1. **Set the full baseURL** including the deep path
+2. **Enable `canonifyURLs = true`** to convert all root-relative URLs to use the baseURL
+3. **Enable `uglyURLs = true`** to reduce (but not eliminate) directory-style links
+4. **Use relative font paths** in CSS (`../fonts/` instead of `/fonts/`) to work across all environments
+5. **Run `add-index-html-links.sh`** to rewrite remaining `href=".../"` links to `href=".../index.html"`
+
+## How to Build
+
+Run these commands from the repository root:
+
+```bash
+# Build the site with the siemens-internal environment
+hugo --environment siemens-internal --cleanDestinationDir
+
+# Rewrite directory-style links to include index.html.
+# The second argument (the site's baseURL) is required: the siemens-internal build uses
+# canonifyURLs=true, which expands all internal links to full absolute URLs. Without the
+# baseURL argument, the script cannot tell internal links from external ones and skips them.
+bash _scripts/add-index-html-links.sh public \
+ https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/
+```
+
+The built site will be in the `public/` directory, ready for deployment to the Siemens internal portal.
+
+## Configuration Files
+
+### Hugo.toml
+
+Sets the baseURL and enables:
+
+* `canonifyURLs = true` to handle the deep deployment path
+* `uglyURLs = true` to ensure proper URL resolution on the Siemens server
+
+### _scripts/add-index-html-links.sh
+
+Rewrites all `href=".../"` directory-style links in the built HTML to `href=".../index.html"` so the Siemens server can serve them without automatic directory index support. Run this after every Hugo build.
+
+Skips external links, anchor links, links that already end in `.html`, and print URLs.
+
+### _scripts/fix-siemens-paths.sh
+
+**Legacy script** — kept for backward compatibility but no longer needed with Hugo v0.156.0+.
+
+Previously used to work around a Hugo bug where `canonifyURLs` generated doubled paths for CSS and JS files. The bug has been fixed, and the script now only prints a confirmation message.
+
+## Technical Details
+
+### Why CanonifyURLs?
+
+The `canonifyURLs = true` setting converts all root-relative URLs (like `/images/foo.svg`) to absolute URLs using the baseURL. This is necessary because:
+
+* Images in templates use hardcoded paths like `/images/...` and `/icons/...`
+* Internal page links need the full path
+* Without it, all these references would be broken
+
+### Why Relative Font Paths?
+
+Font files are referenced in CSS using relative paths (`../fonts/`, `../webfonts/`) rather than root-relative paths (`/fonts/`). This approach:
+
+* Works consistently across all deployment environments (production, development, siemens-internal)
+* Does not require environment-specific processing
+* Avoids issues with deep URL paths
+
+### Hugo Version Requirements
+
+* **Hugo v0.156.0 or later** is required for correct handling of deep baseURL paths with `canonifyURLs`
+* Earlier versions had a bug where `canonifyURLs` would generate doubled paths for CSS and JS assets
+
+## Updating the Deployment Path
+
+If the Siemens deployment URL changes, update the `baseURL` in `config/siemens-internal/hugo.toml`.
+
+## Alternative Approaches Considered
+
+1. **Using relativeURLs**: Breaks the landing page images and requires template changes
+2. **Path-only baseURL**: Requires web server configuration and does not work with direct file access
+3. **Template modifications**: Requires maintaining custom versions of Docsy theme files
+
+The current solution (Hugo configuration plus a focused post-processing script) is the simplest and most maintainable approach.
diff --git a/config/siemens-internal/hugo.toml b/config/siemens-internal/hugo.toml
new file mode 100644
index 00000000000..37370ec4398
--- /dev/null
+++ b/config/siemens-internal/hugo.toml
@@ -0,0 +1,17 @@
+# Merges with _default/config.toml if --environment internal
+# Configuration for internal Siemens documentation deployment
+# Need to set _merge = 'deep' to overwrite original value
+# =============================================================
+
+baseURL = "https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/"
+title = "Mendix Documentation (Internal)"
+
+# Convert all absolute paths (starting with /) to use the full baseURL
+# This fixes images and most links. The CSS path doubling issue can be fixed with post-processing.
+canonifyURLs = true
+
+# Disable robots.txt for internal deployment
+enableRobotsTXT = false
+
+# Enable ugly URLs to help links work on the Siemens site
+uglyURLs = true
\ No newline at end of file