Skip to content

React Skip Link

DodaTech 4 min read

title: "Skip Links in React" weight: 24 description: "Learn how to implement accessible skip links in React applications that allow keyboard users to skip navigation, manage focus correctly in SPAs, and work with React Router and dynamic content." date: 2026-06-28 lastmod: 2026-06-28 tags: [accessibility, react]


Skip links in React allow keyboard and screen reader users to bypass repetitive navigation and jump directly to main content, requiring special handling in SPAs where standard anchor-based skip links may not trigger focus changes correctly.

## What You'll Learn

You will implement skip links in React SPAs, manage focus correctly, ensure skip links work with dynamic content, and style skip links for visibility on focus.

## Why It Matters

Keyboard users must tab through every navigation link before reaching main content. On a site with 30 navigation items, this is exhausting. A skip link lets them jump directly to the content, dramatically improving keyboard navigation.

## Real-World Use

A news site has a navigation with 25 links. A keyboard user must press Tab 25 times before reaching the first article. A skip link reduces this to one Tab press to the skip link plus Enter to activate it.

## Skip Link Implementation

```mermaid
flowchart TD
  A[Page Loads] --> B[First Tab]
  B --> C[Skip Link Visible]
  C --> D[Enter Activates]
  D --> E[Focus to Main Content]
  E --> F[Continue Browsing]

Create a skip link component that works with React Router and dynamic content.

function SkipLink({ targetId = 'main-content', children }) {
  const handleClick = (e) => {
    e.preventDefault();
    const target = document.getElementById(targetId);
    if (target) {
      target.setAttribute('tabindex', '-1');
      target.focus();
      // Remove tabindex after focus so it is not in tab order
      target.addEventListener('blur', () => {
        target.removeAttribute('tabindex');
      }, { once: true });
    }
  };

  return (
    <a
      href={`#${targetId}`}
      className="skip-link"
      onClick={handleClick}
    >
      {children || 'Skip to main content'}
    </a>
  );
}
/* Skip link styling */
.skip-link {
  position: absolute;
  top: -100%;
  left: 16px;
  padding: 12px 24px;
  background: #0056b3;
  color: #fff;
  border-radius: 4px;
  z-index: 1000;
  font-size: 16px;
  min-width: 44px;
  min-height: 44px;
}

.skip-link:focus {
  top: 8px;
}
// App layout with skip link
function AppLayout() {
  return (
    <>
      <SkipLink />
      <header>
        <nav aria-label="Main navigation">
          <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/products">Products</a></li>
            <li><a href="/about">About</a></li>
            <li><a href="/blog">Blog</a></li>
            <li><a href="/contact">Contact</a></li>
            <li><a href="/faq">FAQ</a></li>
            <li><a href="/support">Support</a></li>
          </ul>
        </nav>
      </header>

      <main id="main-content" tabIndex={-1}>
        <Outlet />
      </main>
    </>
  );
}
// Skip link with React Router
import { useLocation } from 'react-router-dom';

function SkipLink() {
  const location = useLocation();

  // Re-focus main content on route change if user is using keyboard
  useEffect(() => {
    const main = document.getElementById('main-content');
    if (main && document.activeElement?.closest('nav')) {
      main.focus();
    }
  }, [location.pathname]);

  return (
    <a
      href="#main-content"
      className="skip-link"
      onClick={(e) => {
        e.preventDefault();
        document.getElementById('main-content').focus();
      }}
    >
      Skip to main content
    </a>
  );
}

Common Mistakes

  • Not making skip link visible on focus
  • Using href="javascript:void(0)" instead of proper href
  • Not setting tabIndex on the target element
  • Forgetting to remove tabIndex after focus
  • Placing skip link inside the navigation it tries to skip
  • Not testing skip link with screen readers
  • Breaking skip links with CSS overflow hidden

Practice and Challenge

Practice 1: Add a skip link to a React app with long navigation. Practice 2: Style skip link to be visible only on focus. Practice 3: Ensure skip link works after React Router navigation. Practice 4: Test skip link with keyboard Tab and Enter. Practice 5: Test skip link with a screen reader.

Challenge: Build a React app with 30 navigation items and implement a skip link that: appears on first Tab press, works on initial page load, works after React Router navigation, focuses the main content, removes tabindex after focus loss, and is visible on focus. Test with keyboard-only navigation and verify the skip link works correctly.

FAQ

Does every page need a skip link?

Yes. Every page with repetitive navigation should have a skip link.

Where should skip link focus go?

Focus should go to the main content area, typically a

element with id='main-content'.

Does href='#main-content' work in SPAs?

No. In SPAs, the hash link does not change focus. Use JavaScript to call .focus() on the target element.

Should skip link be visible all the time?

No. It should be hidden until focused. This reduces visual clutter while remaining accessible.

How do I style skip link?

Position it off-screen with position: absolute; top: -100%; and bring it into view on focus.

What about skip links on mobile?

Skip links work on mobile with external keyboards. They also benefit VoiceOver and TalkBack users.

Mini Project

Create a React skip link component library with: SkipLink (primary skip link), SkipNavigation (skip to nav), SkipToSection (skip to any section by ID), and a useSkipLink hook. Include a demo page with long navigation, multiple sections, and keyboard navigation support. Test the library with axe-core and screen readers.

What's Next

React Accessibility Module Project covers the capstone project for React accessibility.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro