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.

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.

1 participant