`Link`: mark the link to the current page (`aria-current`, `data-active`)

Cerrado
#676 2 comentarios 0 reacciones 1 asignado Ver en GitHub

Los mantenedores suelen responder en 1 día

@yangshun ya está trabajando en esto.

Desde el 3/11/2026.

  • #687 de @yangshun — fusionado

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
25/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
react, typescript
Área
frontend

Línea de trabajo

Start with the shared Link logic that #672 moves into void/pages-client, and read how useRouter() exposes the current path in the React adapter. The open questions are the prop name for prefix matching and whether to match by segment; settle those with maintainers before coding. Done when an exact match sets aria-current="page" and data-active, and activeMatch="prefix" matches whole segments while ignoring query and hash.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Summary

Link renders a plain <a> with no sign that it points to the current page. Every navigation menu (a header, a sidebar, tabs) has to compare useRouter().path with each link's href by hand. Those hand-written checks usually style the active link but forget aria-current="page", so screen readers aren't told which link is the current page.

Example

What an app writes today:

import { Link, useRouter } from '@void/react';

// The section's home link only matches itself; the others also match their nested pages.
function isActive(path: string, href: string, home: string) {
  return path === href || (href !== home && path.startsWith(`${href}/`));
}

function Sidebar({ links, home }: { links: { href: string; label: string }[]; home: string }) {
  const { path } = useRouter();
  return links.map((link) => {
    const active = isActive(path, link.href, home);
    return (
      <Link
        key={link.href}
        href={link.href}
        data-active={active || undefined}
        aria-current={active ? 'page' : undefined}
      >
        {link.label}
      </Link>
    );
  });
}

What it could be:

<Link href="/admin">Overview</Link>
<Link href="/admin/users" activeMatch="prefix">Users</Link>
Proposal
  • aria-current="page" when the link's path is the current path. It's semantically "this is the current page", so exact match only.
  • data-active on the same link, for styling with [data-active] or Tailwind's data-active:. Unlike a class, it doesn't collide with the app's own className.
  • An opt-in for nested pages, for example activeMatch="prefix", so /admin/users stays highlighted on /admin/users/42. It matches whole path segments, so /admin/users doesn't match /admin/users-archive.
  • Ignore the query and hash when matching, so /inbox?page=2 still marks /inbox.

The names are only suggestions. The router already holds the current path in every adapter, so this should look the same in React, Vue, Svelte and Solid. #672, which moves the shared Link logic into void/pages-client, looks like the natural place for the matching.

Prior art
  • React Router: NavLink sets aria-current="page" and an active class, and takes end to choose between exact and nested matching.
  • TanStack Router: Link sets aria-current="page" and data-status="active", and takes activeOptions: { exact, includeSearch } and activeProps.
  • Vue Router: RouterLink adds router-link-active for nested matches, and router-link-exact-active plus aria-current="page" for exact ones.
  • Nuxt: NuxtLink takes activeClass and exactActiveClass.
Environment
  • void 1.5.0
  • @void/react 1.5.0
Lenguaje dominante
TypeScript
Estrellas
627
Forks
66
Merge medio
13 h 57 min
PR fusionados (30 d)
194

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de voidzero-dev/void

Todos los issues de voidzero-dev/void

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.