JavaScript ha trasformato i documenti statici in software. Le single-page app sembrano istantanee. Niente ricaricamenti completi della pagina, niente schermi bianchi lampeggianti. Ma questa velocità ha un costo che molti team ignorano: la meccanica di base del web inizia a deteriorarsi. La navigazione diventa fragile. I motori di ricerca faticano a seguire i percorsi. Gli screen reader si perdono. E gli utenti si ritrovano intrappolati in interfacce che sembrano siti web ma si comportano come applicazioni desktop difettose.

Il colpevole è solitamente un div con un gestore onClick.

Un div non ha alcun significato semantico. È una scatola. Quando gli applichi un gestore di click e lo usi per indirizzare gli utenti verso una nuova vista, stai chiedendo al browser di trattare una scatola di cartone come una porta. Il browser rifiuta. E lo fa anche ogni strumento costruito attorno al browser.

Gli screen reader non annunciano un div come un link o un pulsante. Lo saltano, oppure lo leggono come semplice testo. Un utente che naviga con la voce non può puntarlo. Un crawler di un motore di ricerca, scansionando la tua pagina alla ricerca di URL scopribili, non vede nulla da seguire. La tua rotta potrebbe quasi non esistere.

Peggio ancora, perdi i comportamenti che gli utenti già conoscono. Un vero link permette a qualcuno di fare clic con il tasto destro per aprirlo in una nuova scheda, aggiungere la destinazione ai segnalibri o copiare l'indirizzo per condividerlo. Gli utenti che usano la tastiera si aspettano di premere Tab per raggiungerlo e Invio per aprirlo. Un div non offre nulla di tutto ciò. Anche se aggiungi tabIndex, role="link" e listener per la tastiera, stai ricostruendo, in modo approssimativo, ciò che il browser ti offre gratuitamente. E dimenticherai un caso limite. Succede sempre.

Usa gli anchor per le destinazioni, i button per le azioni

L'HTML ha già risolto il problema. La confusione nasce dal fatto che entrambi gli elementi sembrano cliccabili, quindi gli sviluppatori li trattano come intercambiabili. Non lo sono.

Usa un tag <a quando vuoi spostare l'utente verso un nuovo URL. Non uno scambio di vista simulato, non un cambio di stato, ma una posizione reale. L'attributo href dovrebbe contenere un indirizzo reale:

<a href="/docs">Documentation</a>

Tutto qui. Se l'utente deve andare da qualche parte, usa un link.

Usa un <button> quando accade qualcosa nella pagina corrente. I pulsanti servono per azioni come:

  • Aprire una modale
  • Inviare un modulo
  • Salvare le impostazioni
  • Attivare/disattivare un menu

I link sono per le destinazioni. I pulsanti sono per le azioni. Mescolare le due cose confonde l'interfaccia e rompe le aspettative dell'utente.

Lascia che il browser faccia il suo lavoro

I browser moderni sono il risultato di decenni di evoluzione e standardizzazione. Gestiscono la sicurezza, la cronologia, il prefetching e l'accessibilità meglio di quanto farà mai il tuo JavaScript scritto a mano.

Un vero tag anchor alimenta automaticamente lo stack della cronologia del browser. Funziona con il menu contestuale nativo. Partecipa agli algoritmi di prefetching integrati del browser quando l'utente ci passa sopra con il mouse o gli dà il focus, facendo sembrare la tua app più veloce senza scrivere una riga di codice. Rispetta le preferenze dell'utente per l'apertura dei link. Collabora con i password manager, con gli strumenti

Stop. This is not a URL. It gives the browser no destination. It pollutes the history stack with unusable states. It breaks browser history and accessibility. It is a trap. If you need click behavior without navigation, you need a <button>. Style it to look however you want. CSS does not care whether the element is a button or a link. Your users do.

Write Text That Explains Where the User Is Going

The words inside your link matter. Screen reader users often pull up a list of every link on the page to scan quickly. If your links all say "Read more" or "Click here," that list becomes useless noise.

Be specific. Compare these:

  • Bad: <a href="/security/api-guide">Read more</a>
  • Good: <a href="/security/api-guide">Read the API security guide</a>

The second tells the user exactly what they will find. It gives search engines context about the destination page. It makes your link list navigable. Descriptive link text is one of the cheapest accessibility wins you can earn.

Test Like You Mean It

Architecture means nothing if you do not verify it.

First, test your keyboard flow. Unplug your mouse. Tab through every interactive element on your site. Every genuine link must show a visible focus outline, not a subtle glow that disappears against your background, but a clear ring that a tired eye can spot. Press Enter. It must activate the link. If Tab skips an element, or if Enter does nothing, you have a bug.

Second, test your routes at the server level. Client-side routing is a thin veneer. If a user bookmarks /dashboard/reports and returns tomorrow, or hits refresh, your server must know how to serve that page. Configure your reverse proxy or your server framework to fall back to your application shell for unknown paths, or serve the correct HTML directly. A dead 404 on refresh is not a minor bug. It is a broken promise.

JavaScript is a powerful layer