docs: introduce Mintlify-inspired Material theme#2702
Conversation
|
Overall readability score: 53.98 (🔴 -0.23)
View detailed metrics🟢 - Shows an increase in readability
Averages:
View metric targets
|
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 184 |
| Duplication | 0 |
AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.
TIP This summary will be updated as you push new changes.
There was a problem hiding this comment.
Code Review
This pull request replaces the legacy submodules with a custom, lightweight theme layer over mkdocs-material (upgraded to v9.7.6), introducing custom CSS, Jinja templates, local assets, and a Python hook (image_metadata.py) to inject image dimensions and loading hints at build time. Feedback on these changes highlights two main improvement opportunities: first, explicitly opening the SVG file with a context manager in image_metadata.py to prevent potential file descriptor leaks when using SafeElementTree.iterparse; second, utilizing Jinja's select filter in source-link.html to filter out empty path segments and avoid generating invalid URLs with double slashes.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Pull Request Overview
The PR introduces a significant modernization of the documentation theme. While Codacy results are technically 'up to standards', the review highlights two major logic issues that should be addressed prior to merging: a fragile regex in the image_metadata.py hook that could corrupt HTML output, and a reliance on window.location.origin in version-select.js that will break functionality if the site is hosted on a sub-path.
Additionally, both docs/assets/javascripts/docs-theme.js and theme/hooks/image_metadata.py have been identified as high-risk due to high complexity and a total lack of automated tests. The introduction of binary parsing logic in the Python hook without unit tests is a specific area of concern for long-term stability.
About this PR
- The PR vendors a large volume of third-party JavaScript (Ionicons, core-js) directly into the repository. This increases the maintenance burden and complicates security auditing. Consider if these can be managed via a package manager or served via CDN for public versions.
Test suggestions
- Python hook: Successfully extract dimensions from valid PNG and GIF files.
- Python hook: Successfully parse dimension and viewBox attributes from SVG files.
- Python hook: Handle corrupted image files or IO errors without failing the MkDocs build.
- JavaScript: Version selector correctly identifies the current page in the target version's sitemap before navigating.
- JavaScript: Global keyboard shortcut (Cmd+K / Ctrl+K) successfully focuses the search input.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Python hook: Successfully extract dimensions from valid PNG and GIF files.
2. Python hook: Successfully parse dimension and viewBox attributes from SVG files.
3. Python hook: Handle corrupted image files or IO errors without failing the MkDocs build.
4. JavaScript: Version selector correctly identifies the current page in the target version's sitemap before navigating.
5. JavaScript: Global keyboard shortcut (Cmd+K / Ctrl+K) successfully focuses the search input.
TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback
| xhrSitemap.send(); | ||
| return new Promise(function(resolve) { | ||
| var xhrSitemap = new XMLHttpRequest(); | ||
| var sitemapURL = window.location.origin + versionPath + "/sitemap.xml"; |
There was a problem hiding this comment.
🟡 MEDIUM RISK
Using window.location.origin assumes the documentation is hosted at the root of the domain. This will break version switching and sitemap fetching if the site is served from a sub-path (e.g., /docs/). Use relative paths or MkDocs-provided base URLs.
There was a problem hiding this comment.
also seems a fair comment
There was a problem hiding this comment.
Thanks — looked into this. The docs are deployed at the domain root (docs.codacy.com): pushing to master publishes the Cloud/Latest build to the gh-pages root, and mike publishes each self-hosted version into a sibling directory plus versions.json at the root. So window.location.origin + "/versions.json" and the version/sitemap paths are correct for this deployment. This also predates the theme change — the previous version-select.js used the same origin-based URLs.
It's also why branch/Netlify previews only show "Cloud (Latest)": versions.json is a gh-pages artifact produced by mike and isn't present on previews, so the selector falls back to the single Cloud entry. Merging won't affect production (the master deploy uses keep_files: true, so versions.json and the version subdirs persist).
If we ever host the docs under a sub-path, the correct fix would be to feed the deployment base into the script (e.g. from config.site_url) rather than assuming the origin. Leaving this open for a decision on whether that's worth doing now.
- source-link.html: filter empty path segments with Jinja `select` so an empty `page.meta.path` no longer produces a double slash in the URL (gemini-code-assist review). - image_metadata.py: open SVG files via a context manager before `iterparse` so the file descriptor is released immediately instead of waiting for GC (gemini-code-assist review). - image_metadata.py: match <img> tags without truncating on a '>' inside a quoted attribute value (codacy review). - image_metadata.py: log unreadable images at DEBUG (strict mode promotes WARNING to a build failure, and an unreadable image must never break the build) (codacy review). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Marketing feedback on the footer: - Remove the "Full scan / Free trial / No credit card" tagline line: it has no value without a sign-up CTA, and the header already carries the "Get started" CTA. - Rebalance into three columns - brand tagline (left), links (center), copyright (right) - replacing the previous left/right split. - The floating Zendesk support widget overlapped the bottom-right links. The links are now centered and the footer reserves bottom space; docs-theme.js also flags <html> via an IntersectionObserver when the footer is visible so CSS lifts the widget above the footer (no-op if the widget is absent). Also folds in a review nitpick: replace the deprecated navigator.platform check with navigator.userAgentData.platform (falling back to platform, then the UA string) for the Cmd/Ctrl-K shortcut label. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Ionicons web-component runtime hydrated <ion-icon> elements after page load and lazily fetched each SVG, causing a visible flash / layout shift on every page load. It also vendored ~11 opaque JS chunks that were hard to maintain. Icons must stay local (a CDN URL breaks on air-gapped self-hosted docs), so the fix is to inline the SVGs at build time. - Add theme/partials/icon.html: a Jinja macro icon(name, class="") that includes the source SVG from assets/vendor/ionicons/svg/<name>.svg and injects the shared "docs-icon" class + aria-hidden onto the <svg>. - Replace every <ion-icon> with an icon(...) call across header, search, palette, source, toc, path-item and nav-item partials (dynamic names for the palette toggle and sidebar_icons work as macro arguments). - Remove the two ionicons <script> includes from main.html and delete the 11 vendored ionicons JS chunks. The 27 source SVGs and the MIT LICENSE stay. - Retarget the ion-icon CSS selectors to svg (header.css) and add a .docs-icon base rule (base.css) mirroring the old default sizing and currentColor inheritance. Result: icons are server-rendered inline SVG - zero runtime JS, zero network fetches, no flash / layout shift, and trivially works offline. Verified with a strict mkdocs build: 0 <ion-icon> elements and no references to the deleted JS remain in the generated site; icons render as inline <svg class="docs-icon">. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a custom Material theme layer, but the current implementation is not up to standards according to Codacy. There are critical risks associated with the manual binary parsing and regex-based HTML modification in image_metadata.py, which is susceptible to ReDoS and build failures.
Furthermore, two files exhibit high complexity with zero test coverage: docs-theme.js (126) and image_metadata.py (59). The refactored version picker is a critical path for self-hosted users, yet it has not been verified in a live environment. These issues, alongside the missing unit tests for the image metadata hook, should be addressed before merging.
About this PR
- The version picker logic in
version-select.jswas significantly refactored to use Promises and modern MkDocs events. Given its importance for self-hosted users, this needs verified testing or mock-based unit tests before release.
Test suggestions
- Missing: Image metadata hook correctly parses dimensions for PNG, GIF, and SVG files during build.
- Missing: Version selector correctly fetches sitemap.xml for target versions and redirects to the equivalent page or root.
- Missing: Keyboard accessibility: 'Cmd+K' (or 'Ctrl+K' on Windows) opens search and focus is trapped within the dialog.
- Missing: IntersectionObserver correctly toggles the 'data-docs-footer-visible' attribute to reposition the Zendesk widget.
- Missing: Image framing logic applied only to images meeting the minimum width threshold (280px) that are stand-alone blocks.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Missing: Image metadata hook correctly parses dimensions for PNG, GIF, and SVG files during build.
2. Missing: Version selector correctly fetches sitemap.xml for target versions and redirects to the equivalent page or root.
3. Missing: Keyboard accessibility: 'Cmd+K' (or 'Ctrl+K' on Windows) opens search and focus is trapped within the dialog.
4. Missing: IntersectionObserver correctly toggles the 'data-docs-footer-visible' attribute to reposition the Zendesk widget.
5. Missing: Image framing logic applied only to images meeting the minimum width threshold (280px) that are stand-alone blocks.
Low confidence findings
- The icon vendoring process described in
CONTRIBUTING.mdis manual. There is a risk of broken UI elements if new icons are referenced in Markdown but not manually copied to the theme directory.
TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback
| selector.addEventListener("blur", function() { | ||
| selectorScrollPosition = undefined; | ||
| }); | ||
| window.versionPages = {}; |
There was a problem hiding this comment.
🟡 MEDIUM RISK
Suggestion: Preserve the existing sitemap cache across instant navigations to avoid redundant network requests.
| window.versionPages = {}; | |
| window.versionPages = window.versionPages || {}; |
| var generatedSelect = makeSelect(versionJSON.map(function(i) { | ||
| return {text: i.title, value: i.version}; | ||
| }), currentVersion.version); | ||
| selector.replaceChildren.apply(selector, Array.prototype.slice.call(generatedSelect.options)); |
There was a problem hiding this comment.
⚪ LOW RISK
Suggestion: Simplify this using the spread operator.
| selector.replaceChildren.apply(selector, Array.prototype.slice.call(generatedSelect.options)); | |
| selector.replaceChildren(...generatedSelect.options); |
The quote-aware <img> pattern added earlier tripped Codacy's Critical "inefficient regular expression" (ReDoS) check, failing the quality gate. Revert _IMAGE_TAG to the linear `<img\b[^>]*>` and instead insert the generated attributes right after the `<img` token (rather than before the closing `>`). The output stays valid even when the match stops early at a `>` inside an attribute value, which addresses the original truncation concern without a backtracking-prone regex. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the centered links column. The footer is now two regions: the tagline on the left (no longer bold) and the nav links followed by the copyright grouped together on the right (Pricing · Blog · Support · Privacy · ©). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- server-outline.svg declared fill="none" on the root <svg> instead of on
its shapes. The theme's `.docs-icon { fill: currentColor }` rule overrides
a root fill, so the shapes inherited currentColor and the icon rendered as
a filled blob. Move fill="none" onto each shape (matching every other
outline icon) so it renders as an outline again.
- Footer copyright now drops the " - Automated code review" suffix (stripped
in the footer template only; the site-wide config.copyright is unchanged so
the RSS feed etc. keep the full string).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Opening search triggers Material's scroll-lock, which sets the body to
position: fixed. That dragged the sticky header (and its theme toggle) out
of view and behind the full-screen search overlay, and read as the page
jumping upward.
- Pin the header to the viewport (position: fixed, z-index above the search
overlay) while search is open, so the whole navbar — including the theme
toggle — stays visible and interactive.
- Give the search box enough top margin to clear the pinned header.
- Focus the search input with { preventScroll: true } so opening search never
nudges the scroll position.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Heyo, im redoing the theme of the docs.
Here's the live preview
The docs right now are in need of a lot of love. They look outdated and there's very little attention to how they are structured and organized. Because of this, i would like to start this as a series of changes:
I am not putting the theme within a submodule intentionally. Putting it as a submodule make it hard to make changes on the docs, and since the documentation of the self-hosted has not been updated in the last 2 years, i would rather focus on a quick, and safe solution that allows us to iterate quickly.
This theme was inspired by Mintlify and completely done with Codex.
Yes, its not perfect. Yes, smells like AI spirit. But, it's one step in the right direction.
Doing this will maintain all the functionality the docs have ATM. And reduces migration efforts to other tools / frameworks. TY 👋
TODO:
TESTS:
CANT TEST: