Skip to content

Fix blank redirect stubs for unmapped fragments#9067

Open
hanzei wants to merge 4 commits into
masterfrom
redirect-fragment-fallback
Open

Fix blank redirect stubs for unmapped fragments#9067
hanzei wants to merge 4 commits into
masterfrom
redirect-fragment-fallback

Conversation

@hanzei

@hanzei hanzei commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Why

Visiting a redirect-stub URL with an anchor that wasn't explicitly mapped returns a blank page. For example, http://docs.mattermost.com/configure/environment-configuration-settings.html#database renders nothing — the old configure/… path is a redirect stub, and #database was never added to its fragment map, so the JS logged unknown redirect: database and left the user staring at an empty page.

Redirect stubs (generated from redirects.py via source/_templates/redirect.html) only redirected fragments explicitly listed in redirects.py. Any other fragment hit the else branch and blanked out. The // TODO: redirect the user to a 404 page was also still unimplemented.

Changes

source/_templates/redirect.html:

  1. Broader fallback for unmapped fragments. When a fragment isn't explicitly mapped, redirect to the page's base destination (the - default entry) and carry the original fragment over — anchor names are generally preserved across a page move, so …#database / …#mobile-security now land on the real section instead of a blank stub. Fixes the whole class of unmapped-anchor links.
  2. Resolved the // TODO. When no redirect can be resolved at all (no matching fragment and no base entry), the user is sent to /404.html instead of a blank page.
  3. Own-property lookup. fragment_redirects is a plain object, so fragment in … also matched inherited members (#toString, #constructor, …), passing a non-string to redirectTo(). Switched to Object.prototype.hasOwnProperty.call.
  4. Extracted the leading-/ → absolute-origin handling into a small redirectTo() helper, and log the fallback at console.debug (not warn) so routine redirects stay quiet.

source/redirects.py:

  1. Removed 233 now-redundant fragment redirects. With the fallback in place, any entry whose target is exactly <base-target>#<same-fragment> is redundant — the fallback produces the identical destination. Kept untouched: fragments on pages with no base entry (the fallback can't reach them → they'd 404), fragments pointing to a different page, and fragments whose anchor was renamed at the destination. (2166 → 1933 entries.)

Verification

  • Verified in a browser against the PR preview: both direct navigation and the redirect path land #database exactly 150px below the fixed header (matching section[id] { scroll-margin-top }), stable across the full page load. Works in Chrome and Firefox. (There's a pre-existing Edge-only quirk where a long page's late reflow leaves the anchor slightly high — unrelated to this change and out of scope.)
  • redirects.py re-imports cleanly; 0 redundant entries remain; the 34 no-base fragment entries are preserved.

🤖 Generated with Claude Code

Redirect stub pages only redirected anchors explicitly listed in
redirects.py. Any other fragment (e.g. environment-configuration-settings
.html#mobile-security) logged "unknown redirect" and left the user on a
blank page.

Now an unmapped fragment falls back to the page's base redirect, carrying
the original fragment over (anchor names are generally preserved across a
page move). When no redirect can be resolved at all, send the user to the
404 page instead of leaving a blank stub (resolves the existing TODO).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6901cbe4-de32-4b63-865b-b955a55786f8

📥 Commits

Reviewing files that changed from the base of the PR and between 888741e and 3bd9417.

📒 Files selected for processing (2)
  • source/_templates/redirect.html
  • source/redirects.py
💤 Files with no reviewable changes (1)
  • source/redirects.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • source/_templates/redirect.html

📝 Walkthrough

Walkthrough

The redirect template now uses a helper for fragment-based navigation, falls back to base-page redirects with preserved fragments, and sends unresolved fragments to /404.html. The redirect map also updates many documentation redirect targets and anchor entries.

Changes

Redirect navigation updates

Layer / File(s) Summary
Fragment redirect flow
source/_templates/redirect.html
The fragment redirect path now delegates direct mappings to a helper, appends the original fragment to base-page redirects when needed, and redirects unresolved fragments to /404.html.
Administration and help redirects
source/redirects.py
Redirect entries change for command-line tools, eDiscovery, config settings, deployment pages, and messaging help pages.
Messaging redirects
source/redirects.py
Redirect coverage changes for channel settings, theme colors, formatting, mentions, sidebar organization, searching, status, file sharing, and related messaging pages.
Onboarding, welcome, and playbooks redirects
source/redirects.py
Redirect entries change for onboarding, shared channels, subscription, playbooks, welcome pages, and the end-user guide.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main fix: handling unmapped redirect fragments to avoid blank pages.
Description check ✅ Passed The description is directly about the redirect-stub fragment fix and matches the changes in the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch redirect-fragment-fallback

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@source/_templates/redirect.html`:
- Around line 31-33: The fragment lookup in redirect.html is using the
fragment_redirects object with an in check, which can match inherited properties
and lead redirectTo() to receive a non-string value. Update the fragment lookup
in the redirect logic to use an own-property check on fragment_redirects before
calling redirectTo(), and apply the same safe pattern to the DEFAULT_PAGE
fallback so only real redirect entries are used.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eaa314dd-ad17-4381-943a-5cbfa6eeecd3

📥 Commits

Reviewing files that changed from the base of the PR and between 6e6ca68 and 888741e.

📒 Files selected for processing (1)
  • source/_templates/redirect.html

Comment thread source/_templates/redirect.html Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Newest code from mattermost has been published to preview environment for Git SHA 888741e

fragment_redirects is a plain object, so `in` also matches inherited
Object.prototype members. A URL like ...#toString passed FRAGMENT_REGEX
and matched the inherited toString function, sending a non-string to
redirectTo(). Use Object.prototype.hasOwnProperty.call so only real
redirect entries are matched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Newest code from mattermost has been published to preview environment for Git SHA c03e13c

@hanzei hanzei requested a review from esethna June 25, 2026 07:53
@hanzei hanzei added the 1: Dev Review Requires review by a core commiter label Jun 25, 2026
hanzei and others added 2 commits June 25, 2026 09:58
The fallback now also backs the explicit fragment redirects we're about to
remove, so downgrade the log from console.warn to console.debug to avoid
warning noise on routine redirects.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The redirect stub now falls back to a page's base redirect and carries the
original fragment over. That makes fragment redirects whose target is
exactly <base-target>#<same-fragment> redundant: the fallback produces the
identical destination.

Remove the 233 such entries. Kept untouched:
- fragments on pages with no base entry (the fallback can't reach them),
- fragments pointing to a different page, and
- fragments whose anchor was renamed at the destination.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Newest code from mattermost has been published to preview environment for Git SHA 3bd9417

Comment thread source/redirects.py

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.

These are not needed any longer. The new code handles them automatically.

@esethna esethna 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.

Thanks @hanzei. Can you confirm that it's intentional you have removed so many redirects? Spot checking a few seem to be causing missed subsection redirects, for example: /administration/ediscovery.html#mattermost-restful-api

Also I noticed that mistyped or invalid URLs now are leading to a 404 page vs current behaviour of at least landing them at the home docs.mattermost.com. For example https://docs.mattermost.com/admin (page does not exist)

Is there a safer way we can make this change to avoid blank pages without potential regressions?

@esethna

esethna commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Friendly ping @hanzei ^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1: Dev Review Requires review by a core commiter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants