Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

An older navigation can overwrite the URL after a newer navigation commits

Ouverte
#507 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
55/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
node.js, playwright, typescript
Domaine
frontend, testing

Piste de recherche

Read packages/void/src/pages/navigation-engine.ts around makeCommit() and packages/void/src/pages/client.ts around applyNavigationResource(). Run the reported parallel-integration Playwright test and inspect how it controls adapter update timing. Add regression coverage for both completion orders and the normal-navigation control; done means a superseded navigation cannot change the URL, head, scroll, or Deferred ownership, and the reproduction leaves both page and URL at /b.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Description

An earlier navigation can commit its URL after a later navigation has already rendered and committed. This leaves the displayed page and browser URL pointing to different destinations.

Unlike #506, this occurs with default navigation options, without preserveState: true.

Environment

  • Commit: 2ceab89154dc6e0c3fa5525f7bd4d1d5f3d0aa64
  • Package version: 1.1.12
  • OS: Ubuntu 24.04.3 LTS x86_64
  • Node: 24.21.0
  • Vite+: 1.3.0; Vitest: 5.0.5
  • Playwright: 1.64.1
  • Chromium Headless Shell: 134.0.6998.35

Steps to reproduce

  1. Initialize the production createVoidRouter() in a browser fixture with valid Pages responses for /a and /b, with View Transitions disabled.
  2. Provide an adapter whose applyUpdate() updates the displayed page but returns a controllable Promise for /a:
let releaseA!: () => void;
let enteredA!: () => void;

const gate = new Promise<void>(resolve => {
  releaseA = resolve;
});
const entered = new Promise<void>(resolve => {
  enteredA = resolve;
});

const adapter = {
  // Other adapter methods omitted.
  applyUpdate(pageData: { url: string }) {
    document.getElementById('app')!.textContent = pageData.url;

    if (pageData.url === '/a') {
      enteredA();
      return gate;
    }
  },
};
  1. Start navigation A, allow B to finish, and then release A:
const visitA = router.visit('/a');
await entered;

await router.visit('/b');

releaseA();
await visitA;
  1. Compare the displayed page with window.location.pathname.

Actual behavior

The older navigation overwrites the URL after the newer navigation has committed:

Value Result
Displayed page /b
window.location.pathname /a

A newly added Playwright integration test reproduced this in both runs. The normal-navigation control passed in both runs.

The test was executed through the repository's parallel-integration project:

vp test run packages/void/test/integration/pages-navigation-race.test.ts --project parallel-integration

The fixture serves the production Pages client through a local HTTP server and controls the adapter's update timing. This verifies the Core/browser race; it is not a full production-build test across every framework adapter.

Expected behavior

The displayed page and browser URL should both remain /b.

Once B has superseded A and committed, completing A's pending adapter update should not allow A to commit its URL or other navigation side effects.

Relevant implementation

In packages/void/src/pages/navigation-engine.ts, makeCommit() uses the pending resource ID when clearing pending state, but that check does not guard the remaining commit operations.

applyNavigationResource() in packages/void/src/pages/client.ts awaits the adapter update and then calls resource.commit(). Consequently, the older resource can still reach the history-writing path after the newer resource has committed.

Acceptance criteria

  • A superseded navigation cannot overwrite the URL after a newer navigation commits.
  • The reproduction above leaves both the displayed page and URL at /b.
  • A superseded commit does not overwrite the newer page's head, scroll, or Deferred resource ownership.
  • Regression coverage includes controlled adapter-update completion orders and a normal-navigation control.
Langage dominant
TypeScript
Étoiles
402
Forks
32
Merge moyen
11 h 52 min
PR mergées (30 j)
88

Préparer son environnement

Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de voidzero-dev/void

Toutes les issues de voidzero-dev/void

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.