Skip to content

Render skip-to-main-content as a link instead of a button - #5610

Merged
tdonohue merged 2 commits into
DSpace:mainfrom
bram-atmire:fix/5605-skip-link-anchor
Oct 7, 2026
Merged

tdonohue merged 2 commits into
DSpace:mainfrom
bram-atmire:fix/5605-skip-link-anchor

Conversation

@bram-atmire

@bram-atmire bram-atmire commented May 4, 2026 •

Copy link
Copy Markdown
Member

References

Description

Render the skip-to-main-content control as routerLink instead of a <button>. Aligns with the canonical WAI-ARIA Authoring Practices skip-link pattern and removes the JS click-handler dependency.

Instructions for Reviewers

List of changes in this PR:

  • src/app/root/root.component.html - modified the skip control to becomes a routerLink. Added tabindex="-1" to <main id="main-content"> so the fragment navigation reliably moves focus across browsers (without tabindex, some browsers do not move focus to non-form elements after fragment navigation).
  • src/app/root/root.component.ts - removed the now-unused skipToMainContent() method that previously focused #main-content programmatically.
  • src/app/root/root.component.spec.ts - added specs asserting (1) the skip link is an <a>, and (2) the <main> target carries tabindex="-1".

How to test:
Test the following scenario in both prod mode & dev mode and try it out on at least 2 different tabs:

  1. Reload a page and press Tab. The screenreader should focus on the "Skip to main content"
  2. Press Enter. The URL should gain #main-content and keyboard focus should land on the <main> element. A subsequent Tab should move focus to the first interactive element inside the page content rather than back to a navbar item.

This is not fixing a current WCAG failure (the existing button works for any user who reaches the running SPA, since DSpace requires JS to render). It aligns the implementation with the canonical pattern - see #5605 for full rationale.

Checklist

  • My PR is created against the main branch of code (unless it is a backport or is fixing an issue specific to an older branch).
  • My PR is small in size (3 files, 19 insertions, 11 deletions).
  • My PR passes ESLint validation using npm run lint
  • My PR doesn't introduce circular dependencies (verified via npm run check-circ-deps)
  • My PR includes TypeDoc comments for all new (or modified) public methods and classes. (n/a - method removed, no new methods)
  • My PR passes all specs/tests and includes new/updated specs or tests based on the Code Testing Guide.
  • My PR aligns with Accessibility guidelines if it makes changes to the user interface.
  • My PR uses i18n (internationalization) keys instead of hardcoded English text, to allow for translations. (existing key root.skip-to-content retained)
  • My PR includes details on how to test it.
  • If my PR includes new libraries/dependencies (in package.json), I've made sure their licenses align with the DSpace BSD License based on the Licensing of Contributions documentation. (n/a)
  • If my PR includes new features or configurations, I've provided basic technical documentation in the PR itself. (n/a)
  • If my PR fixes an issue ticket, I've linked them together.

@lgeggleston lgeggleston added improvement accessibility 1 APPROVAL pull request only requires a single approval to merge labels May 4, 2026
@lgeggleston lgeggleston moved this to 🙋 Needs Reviewers Assigned in DSpace 10.0 Release May 4, 2026

@GauravD2t GauravD2t 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 @bram-atmire ! I have thoroughly tested all the steps outlined in the review instructions, and everything is working perfectly as expected.

@lgeggleston lgeggleston moved this to 👍 Reviewer Approved in DSpace 11.0 Release Jun 2, 2026
@alexandrevryghem
alexandrevryghem force-pushed the fix/5605-skip-link-anchor branch from 4e9d155 to 3e38c8d Compare August 7, 2026 13:41
@alexandrevryghem alexandrevryghem changed the title Render skip-to-main-content as <a href="#main-content"> instead of a button Render skip-to-main-content as a link instead of a button Aug 7, 2026
@alexandrevryghem
alexandrevryghem marked this pull request as ready for review August 7, 2026 13:49

@alexandrevryghem alexandrevryghem left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The previous code did not work properly in developer mode and browsers that use JavaScript because it forced a page reload. I replaced the href with a routerLink which ensures the page is not reloaded anymore and the navigation is now handled by Angular internally.

I've verified this also works correctly in prod mode when you disabled Javascript & updated the PR description

@lgeggleston lgeggleston added port to dspace-9_x This PR needs to be ported to `dspace-9_x` branch for next bug-fix release port to dspace-10_x This PR needs to be ported to `dspace-10_x` branch for next bug-fix release labels Aug 14, 2026
@tdonohue
tdonohue self-requested a review August 18, 2026 18:32
@lgeggleston lgeggleston moved this from 👍 Reviewer Approved to Merge Ready in DSpace 11.0 Release Sep 23, 2026
@tdonohue tdonohue added the port to dspace-8_x This PR needs to be ported to `dspace-8_x` branch for next bug-fix release label Oct 7, 2026
@tdonohue tdonohue added this to the 11.0 milestone Oct 7, 2026

@tdonohue tdonohue left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

👍 Thanks @bram-atmire ! This looks good to me too.

@tdonohue
tdonohue merged commit 5753b45 into DSpace:main Oct 7, 2026
16 checks passed
@dspace-bot

Copy link
Copy Markdown
Contributor

Backport failed for dspace-8_x, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin dspace-8_x
git worktree add -d .worktree/backport-5610-to-dspace-8_x origin/dspace-8_x
cd .worktree/backport-5610-to-dspace-8_x
git switch --create backport-5610-to-dspace-8_x
git cherry-pick -x a24a5d6f0198a2147edc48f6f215020371a7f00d

@dspace-bot

Copy link
Copy Markdown
Contributor

Successfully created backport PR for dspace-9_x:

@dspace-bot

Copy link
Copy Markdown
Contributor

Backport failed for dspace-10_x, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin dspace-10_x
git worktree add -d .worktree/backport-5610-to-dspace-10_x origin/dspace-10_x
cd .worktree/backport-5610-to-dspace-10_x
git switch --create backport-5610-to-dspace-10_x
git cherry-pick -x a24a5d6f0198a2147edc48f6f215020371a7f00d

@tdonohue

tdonohue commented Oct 7, 2026

Copy link
Copy Markdown
Member

@bram-atmire : Somewhat strangely, this could only be backported to 9.x. So, that means it's missing from 10.x and 8.x. Could you create a backport PR minimally for 10.x against the dspace-10_x branch? This seems useful to at least get into 9.x and 10.x...but I'd also support backporting to 8.x as well if you have time.

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

Labels

1 APPROVAL pull request only requires a single approval to merge accessibility improvement port to dspace-8_x This PR needs to be ported to `dspace-8_x` branch for next bug-fix release port to dspace-9_x This PR needs to be ported to `dspace-9_x` branch for next bug-fix release port to dspace-10_x This PR needs to be ported to `dspace-10_x` branch for next bug-fix release

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

Cleanup: use <a href="#main-content"> for the skip link to align with the canonical pattern

6 participants