Skip to content

docs: introduce Mintlify-inspired Material theme#2702

Open
claudiacodacy wants to merge 8 commits into
masterfrom
codex/mintlify-material-theme-squashed
Open

docs: introduce Mintlify-inspired Material theme#2702
claudiacodacy wants to merge 8 commits into
masterfrom
codex/mintlify-material-theme-squashed

Conversation

@claudiacodacy

@claudiacodacy claudiacodacy commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

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:

  1. Change the theme of the docs
  2. Review content and start reorganizing content in a meaningful way
  3. Review and restructure release notes

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:

  • Improve ionicons import / load

TESTS:

  • Build passes
  • Pages render correctly

CANT TEST:

  • Version picker

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Overall readability score: 53.98 (🔴 -0.23)

File Readability
index.md 34.49 (🔴 -65.51)
index.md 82.53 (🟢 +7.39)
managing-security-and-risk.md 58.36 (🔴 -0.35)
supported-languages-and-tools.md 49.15 (🟢 +0)
codacy-quickstart.md 50.97 (🟢 +0)
codacy-guardrails-getting-started.md 59.44 (🟢 +0)
index.md 63.75 (🟢 +0)
nav-multistep-quickstart.md 100 (🟢 +0)
emails.md 51.59 (🟢 +0)
View detailed metrics

🟢 - Shows an increase in readability
🔴 - Shows a decrease in readability

File Readability FRE GF ARI CLI DCRS
index.md 34.49 24.78 16.02 15.1 12.3 9.19
  🔴 -65.51 🔴 -75.22 🔴 -10.02 🔴 -9.1 🔴 -6.3 🔴 -4.29
index.md 82.53 93.14 7.29 10.1 8.92 6.16
  🟢 +7.39 🟢 +5.08 🟢 +1.87 🟢 +1.9 🟢 +0.07 🟢 +0.15
managing-security-and-risk.md 58.36 36.69 9.8 12.9 12.82 6.46
  🔴 -0.35 🔴 -0.2 🔴 -0.08 🔴 -0.1 🟢 +0 🔴 -0.01
supported-languages-and-tools.md 49.15 31.17 10.81 13.1 14.2 7.81
  🟢 +0 🟢 +0 🟢 +0 🟢 +0 🟢 +0 🟢 +0
codacy-quickstart.md 50.97 38.21 11.7 12.4 13.05 7.95
  🟢 +0 🟢 +0 🟢 +0 🟢 +0 🟢 +0 🟢 +0
codacy-guardrails-getting-started.md 59.44 48.64 11.41 13.2 10.62 6.71
  🟢 +0 🟢 +0 🟢 +0 🟢 +0 🟢 +0 🟢 +0
index.md 63.75 42.88 9.03 9.7 11.29 7.63
  🟢 +0 🟢 +0 🟢 +0 🟢 +0 🟢 +0 🟢 +0
nav-multistep-quickstart.md 100 100 6 6 6 4.9
  🟢 +0 🟢 +0 🟢 +0 🟢 +0 🟢 +0 🟢 +0
emails.md 51.59 40.08 12.02 14.5 12.42 7.01
  🟢 +0 🟢 +0 🟢 +0 🟢 +0 🟢 +0 🟢 +0

Averages:

  Readability FRE GF ARI CLI DCRS
Average 53.98 42.98 10.93 12.34 12.28 8.04
  🔴 -0.23 🔴 -0.27 🔴 -0.03 🔴 -0.03 🔴 -0.02 🔴 -0.02
View metric targets
Metric Range Ideal score
Flesch Reading Ease 100 (very easy read) to 0 (extremely difficult read) 60
Gunning Fog 6 (very easy read) to 17 (extremely difficult read) 8 or less
Auto. Read. Index 6 (very easy read) to 14 (extremely difficult read) 8 or less
Coleman Liau Index 6 (very easy read) to 17 (extremely difficult read) 8 or less
Dale-Chall Readability 4.9 (very easy read) to 9.9 (extremely difficult read) 6.9 or less

@codacy-production

codacy-production Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 184 complexity · 0 duplication

Metric Results
Complexity 184
Duplication 0

View in Codacy

AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.

Run reviewer

TIP This summary will be updated as you push new changes.

@github-actions github-actions Bot temporarily deployed to Netlify July 14, 2026 15:18 Inactive

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread theme/hooks/image_metadata.py Outdated
Comment thread theme/partials/source-link.html Outdated

@codacy-production codacy-production Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also seems a fair comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread theme/hooks/image_metadata.py
Comment thread docs/assets/javascripts/docs-theme.js
Comment thread docs/assets/javascripts/version-select.js
Comment thread theme/hooks/image_metadata.py
Comment thread docs/assets/javascripts/docs-theme.js Outdated
claudiacodacy and others added 3 commits July 14, 2026 19:56
- 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>
@github-actions github-actions Bot temporarily deployed to Netlify July 14, 2026 19:05 Inactive

@codacy-production codacy-production Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.js was 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.md is 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

Comment thread theme/hooks/image_metadata.py Outdated
selector.addEventListener("blur", function() {
selectorScrollPosition = undefined;
});
window.versionPages = {};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MEDIUM RISK

Suggestion: Preserve the existing sitemap cache across instant navigations to avoid redundant network requests.

Suggested change
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));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚪ LOW RISK

Suggestion: Simplify this using the spread operator.

Suggested change
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>
@github-actions github-actions Bot temporarily deployed to Netlify July 14, 2026 19:53 Inactive
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>
@github-actions github-actions Bot temporarily deployed to Netlify July 14, 2026 20:33 Inactive
- 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>
@github-actions github-actions Bot temporarily deployed to Netlify July 14, 2026 20:36 Inactive
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants