MTL ExplorerReleased · 0.9.0Home

Generate and check the website

The product introduction and feature tours live in docs/. Documentation is generated from the audience folders in documentation/; the installed guide uses the same sources. The homepage update link, news, and docs/releases/ are generated from the versioned release notes. Edit those Markdown files, not generated pages or marked homepage/sitemap regions. These helpers do not publish anything.

The same generation writes docs/releases/releases.json from published notes and the verified image catalog. Drafts stay out of update offers. See the publication and E2E flow.

Shared colors and six text-size roles live in docs/site-theme.css. Reuse those tokens in homepage, guide, and release styles; reserve blue for actions and accents. The installed guide loads documentation/tools/website/guide-theme.js before its styles to follow the app's saved theme. Dark guide colors live in documentation.css; print output uses the light palette.

Guide navigation uses compact desktop rows and larger mobile targets. The topic menu and article outline collapse below 960px. Edit the shared layout in generate_documentation.py, documentation.css, and documentation.js, then regenerate both outputs.

App guide links retain the same-origin app tab as their opener. The installed guide-navigation.js returns to that running tab and closes the guide on Back to app. Direct guide visits use the app link as a fallback. Links outside the guide open separately without access to the app tab.

In an active Python virtual environment, install the release generator's dependency, then generate and check the pages:

python -m pip install -r documentation/tools/website/requirements.txt
python documentation/tools/website/generate_documentation.py
python documentation/tools/website/generate_releases.py
python documentation/tools/website/generate_documentation.py --check
python documentation/tools/website/generate_releases.py --check
python documentation/tools/website/check_documentation.py
python documentation/tools/website/check_memory_profile.py
python -m unittest discover -s documentation/tools/tests -p 'test_website_releases.py'
node --test documentation/tools/tests/test_site_analytics.mjs

python3 documentation/tools/build.py docs regenerates the guide and checks release-page freshness. Regenerate release pages with generate_releases.py after editing release notes. Use build.py docs --check to check both outputs without writing.

The memory check requires the Docker Compose CLI but does not start containers. It compares service limits, paired tuning settings, and the memory guide's Compose example with the shipped templates.

Generation reads the explicit teaser: >- metadata field for banner, news, archive summaries, and release-page descriptions. It inserts that same teaser below the H1 in full website and GitHub notes. Teasers are plain text, limited to 160 characters; see the authoring convention. The news headline and banner identify the version independently of chapter order. The banner sits above the homepage hero and links to the full notes. A null publication date means Upcoming; the latest published release is selected by date and version. Generated output is committed with its Markdown source. The mirror publisher refreshes this output before copying the site and prepares the same teaser and Markdown body for GitHub Releases without metadata. Use the same virtual environment when running ../mtl-explorer-private/publish-to-github.py.

python3 documentation/tools/website/check_seo.py
python3 -m http.server 8765 --bind 127.0.0.1 --directory docs

With the preview running, check its HTML against the working copy:

python3 documentation/tools/website/check_seo.py --base-url http://127.0.0.1:8765/

The check covers canonicals, old-domain references, unique metadata, H1/main, JSON-LD, breadcrumbs, image dimensions, local resources/fragments, sitemap, robots, and navigation reachability. --base-url additionally reads the HTML, sitemap, and robots over HTTP and compares their bytes with local files. It does not fetch every asset or verify external links, indexing, or rich-result eligibility. The offline check is the default.

Synthetic GPX examples are generated by generate_examples.py. See the example notes. Real screenshots of year filters use the public demo dataset; see the capture notes. Segment screenshots were captured on 6 September 2026 with public demo routes in an isolated local backend; see the capture notes.

Google Health images are real app captures with synthetic data; see their source notes. Capture from the current app through the Codex in-app browser, using public or fully synthetic data. Keep raw captures on the external drive. With Pillow available, encode the two JPEG captures at the website's four WebP sizes:

python documentation/tools/website/prepare_health_screenshots.py /Volumes/EXT_HD_1TB/mytraillog/website-health-refresh/2026-10-03

The helper preserves screenshot content and aspect ratio, never upscales, and reports dimensions and byte sizes. Match HTML dimensions and srcset widths to that output; update image cache versions and source notes when replacing captures.

When a release is explicitly requested, use ../mtl-explorer-private/publish-to-github.py and then run the read-only check against https://mtl-explorer.com/. Inspect Search Console separately for the selected canonicals and the sitemap's successful read.

Product tours, release pages and every generated public documentation page load analytics from docs/site-analytics.js. The installed app guide instead loads guide-analytics.js, which follows the application's optional Umami configuration. The page's hostname selects the configuration automatically:

Page hostname Tracker host Umami website ID
mtl-explorer.com stats.mtl-explorer.com eb0877dd-d24d-4a5d-8735-eaeed78f0f38
localhost, 127.0.0.1, [::1] (any port) umami.me.mindalyze.com c221b96a-f9e6-4f6a-b272-2f6649371876
Other hostnames or files opened directly Disabled —

The preview command above uses the test website. Publishing the same files at mtl-explorer.com uses production automatically. The tracker starts asynchronously after window load and respects Do Not Track in both environments. Page code does not wait for analytics. Query strings and fragments are excluded, including campaign query parameters. There are no custom click events or tracking-dependent navigation.

The website and installed guide use Umami's default anonymous visitor and session identification. They supply no Distinct ID and create no custom identifier in local or session storage. Generated public documentation links to the homepage's Site analytics notice.

When changing tracking, verify the selected host and website ID in both environments, then check a blocked/hanging script and a failed/hanging collector in a browser. Pages must finish loading and their links and screenshot controls must work in every case. Intercept test submissions so local verification does not add synthetic visits to the live analytics database.

Component release previews: add --components to prepare_update_preview. Release manifests and ownership settings: release updates.