JavaScript ਨੇ ਸਟੈਟਿਕ ਦਸਤਾਵੇਜ਼ਾਂ ਨੂੰ ਸਾਫਟਵੇਅਰ ਵਿੱਚ ਬਦਲ ਦਿੱਤਾ ਹੈ। Single-page apps ਬਹੁਤ ਤੇਜ਼ ਮਹਿਸੂਸ ਹੁੰਦੀਆਂ ਹਨ। ਕੋਈ ਪੂਰਾ ਪੇਜ ਰੀਲੋਡ ਨਹੀਂ, ਕੋਈ ਫਲਿੱਕਰਿੰਗ ਵ੍ਹਾਈਟ ਸਕ੍ਰੀਨ ਨਹੀਂ। ਪਰ ਇਸ ਰਫ਼ਤਾਰ ਦੀ ਇੱਕ ਕੀਮਤ ਹੈ ਜਿਸ ਨੂੰ ਬਹੁਤ ਸਾਰੀਆਂ ਟੀਮਾਂ ਨਜ਼ਰਅੰਦਾਜ਼ ਕਰ ਦਿੰਦੀਆਂ ਹਨ: ਵੈੱਬ ਦੀ ਬੁਨਿਆਦੀ ਮਸ਼ੀਨਰੀ ਖਰਾਬ ਹੋਣ ਲੱਗਦੀ ਹੈ। Navigation ਨਾਜ਼ੁਕ ਹੋ ਜਾਂਦੀ ਹੈ। Search engines ਨੂੰ ਰਸਤਿਆਂ ਦਾ ਪਤਾ ਲਗਾਉਣ ਵਿੱਚ ਮੁਸ਼ਕਲ ਆਉਂਦੀ ਹੈ। Screen readers ਭਟਕ ਜਾਂਦੇ ਹਨ। ਅਤੇ ਉਪਭੋਗਤਾ ਆਪਣੇ ਆਪ ਨੂੰ ਅਜਿਹੇ ਇੰਟਰਫੇਸਾਂ ਵਿੱਚ ਫਸਿਆ ਹੋਇਆ ਪਾਉਂਦੇ ਹਨ ਜੋ ਵੈੱਬਸਾਈਟਾਂ ਵਾਂਗ ਦਿਖਾਈ ਦਿੰਦੇ ਹਨ ਪਰ ਟੁੱਟੀਆਂ ਹੋਈਆਂ ਡੈਸਕਟਾਪ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵਾਂਗ ਕੰਮ ਕਰਦੇ ਹਨ।
ਇਸਦਾ ਮੁੱਖ ਕਾਰਨ ਆਮ ਤੌਰ 'ਤੇ ਇੱਕ onClick ਹੈਂਡਲਰ ਵਾਲਾ div ਹੁੰਦਾ ਹੈ।
Divs ਨੂੰ Links ਵਜੋਂ ਵਰਤਣਾ ਬੰਦ ਕਰੋ
ਇੱਕ div ਦਾ ਕੋਈ semantic ਮਤਲਬ ਨਹੀਂ ਹੁੰਦਾ। ਇਹ ਸਿਰਫ਼ ਇੱਕ ਡੱਬਾ ਹੈ। ਜਦੋਂ ਤੁਸੀਂ ਇਸ ਉੱਤੇ ਇੱਕ click handler ਲਗਾਉਂਦੇ ਹੋ ਅਤੇ ਇਸਦੀ ਵਰਤੋਂ ਉਪਭੋਗਤਾਵਾਂ ਨੂੰ ਨਵੇਂ view ਵੱਲ ਲੈ ਜਾਣ ਲਈ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁਸੀਂ ਬ੍ਰਾਊਜ਼ਰ ਨੂੰ ਇੱਕ ਗੱਤੇ ਦੇ ਡੱਬੇ ਨੂੰ ਦਰਵਾਜ਼ੇ ਵਾਂਗ ਵਰਤਣ ਲਈ ਕਹਿ ਰਹੇ ਹੁੰਦੇ ਹੋ। ਬ੍ਰਾਊਜ਼ਰ ਇਸ ਤੋਂ ਇਨਕਾਰ ਕਰ ਦਿੰਦਾ ਹੈ। ਅਤੇ ਬ੍ਰਾਊਜ਼ਰ ਦੇ ਆਲੇ-ਦੁਆਲੇ ਬਣਿਆ ਹਰ ਟੂਲ ਵੀ ਇਹੀ ਕਰਦਾ ਹੈ।
Screen readers ਇੱਕ div ਨੂੰ ਲਿੰਕ ਜਾਂ ਬਟਨ ਵਜੋਂ ਨਹੀਂ ਦੱਸਦੇ। ਉਹ ਇਸਨੂੰ ਛੱਡ ਦਿੰਦੇ ਹਨ, ਜਾਂ ਇਸਨੂੰ ਸਾਧਾਰਨ ਟੈਕਸਟ ਵਜੋਂ ਪੜ੍ਹਦੇ ਹਨ। ਆਵਾਜ਼ ਰਾਹੀਂ ਨੈਵੀਗੇਟ ਕਰਨ ਵਾਲਾ ਉਪਭੋਗਤਾ ਇਸਨੂੰ ਟਾਰਗੇਟ ਨਹੀਂ ਕਰ ਸਕਦਾ। ਇੱਕ search engine crawler, ਜੋ ਤੁਹਾਡੇ ਪੇਜ 'ਤੇ discoverable URLs ਦੀ ਭਾਲ ਕਰ ਰਿਹਾ ਹੁੰਦਾ ਹੈ, ਉਸਨੂੰ ਫੋਲੋ ਕਰਨ ਲਈ ਕੁਝ ਵੀ ਨਹੀਂ ਮਿਲਦਾ। ਤੁਹਾਡਾ route ਸ਼ਾਇਦ ਮੌਜੂਦ ਹੀ ਨਾ ਹੋਵੇ।
ਇਸ ਤੋਂ ਵੀ ਮਾੜਾ ਇਹ ਹੈ ਕਿ ਤੁਸੀਂ ਉਹ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਗੁਆ ਲੈਂਦੇ ਹੋ ਜੋ ਉਪਭੋਗਤਾ ਪਹਿਲਾਂ ਹੀ ਜਾਣਦੇ ਹਨ। ਇੱਕ ਅਸਲੀ ਲਿੰਕ ਕਿਸੇ ਨੂੰ ਨਵੇਂ ਟੈਬ ਵਿੱਚ ਖੋਲ੍ਹਣ ਲਈ right-click ਕਰਨ, ਮੰਜ਼ਿਲ ਨੂੰ bookmark ਕਰਨ, ਜਾਂ ਸਾਂਝਾ ਕਰਨ ਲਈ ਪਤਾ (address) ਕਾਪੀ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ। Keyboard ਉਪਭੋਗਤਾ ਉਮੀਦ ਕਰਦੇ ਹਨ ਕਿ ਉਹ ਇਸ ਤੱਕ ਪਹੁੰਚਣ ਲਈ Tab ਦਬਾਉਣਗੇ ਅਤੇ ਇਸਨੂੰ ਖੋਲ੍ਹਣ ਲਈ Enter। ਇੱਕ div ਇਹਨਾਂ ਵਿੱਚੋਂ ਕੁਝ ਵੀ ਨਹੀਂ ਦਿੰਦਾ। ਭਾਵੇਂ ਤੁਸੀਂ tabIndex ਅਤੇ role="link" ਅਤੇ keyboard listeners ਲਗਾ ਵੀ ਦਿਓ, ਫਿਰ ਵੀ ਤੁਸੀਂ ਉਸ ਚੀਜ਼ ਨੂੰ ਬਹੁਤ ਮਾੜੇ ਤਰੀਕੇ ਨਾਲ ਦੁਬਾਰਾ ਬਣਾ ਰਹੇ ਹੋ ਜੋ ਬ੍ਰਾਊਜ਼ਰ ਤੁਹਾਨੂੰ ਮੁਫ਼ਤ ਵਿੱਚ ਦਿੰਦਾ ਹੈ। ਅਤੇ ਤੁਸੀਂ ਕਿਸੇ edge case ਨੂੰ ਭੁੱਲ ਜਾਓਗੇ। ਤੁਸੀਂ ਹਮੇਸ਼ਾ ਭੁੱਲ ਜਾਂਦੇ ਹੋ।
ਮੰਜ਼ਿਲਾਂ ਲਈ Anchors ਅਤੇ ਕਾਰਵਾਈਆਂ ਲਈ Buttons ਦੀ ਵਰਤੋਂ ਕਰੋ
HTML ਨੇ ਇਸਦਾ ਹੱਲ ਪਹਿਲਾਂ ਹੀ ਕੱਢ ਲਿਆ ਹੈ। ਉਲਝਣ ਇਸ ਲਈ ਸ਼ੁਰੂ ਹੁੰਦੀ ਹੈ ਕਿਉਂਕਿ ਦੋਵੇਂ elements ਕਲਿੱਕੇਬਲ (clickable) ਲੱਗਦੇ ਹਨ, ਇਸ ਲਈ ਡਿਵੈਲਪਰ ਉਹਨਾਂ ਨੂੰ ਇੱਕ-ਦੂਜੇ ਦੀ ਜਗ੍ਹਾ ਵਰਤ ਲੈਂਦੇ ਹਨ। ਪਰ ਉਹ ਅਜਿਹੇ ਨਹੀਂ ਹਨ।
ਜਦੋਂ ਤੁਸੀਂ ਉਪਭੋਗਤਾ ਨੂੰ ਨਵੇਂ URL 'ਤੇ ਲੈ ਕੇ ਜਾਣਾ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ <a\> ਟੈਗ ਦੀ ਵਰਤੋਂ ਕਰੋ। ਕੋਈ ਨਕਲੀ view swap ਨਹੀਂ, ਕੋਈ state change ਨਹੀਂ, ਬਲਕਿ ਇੱਕ ਅਸਲੀ ਲੋਕੇਸ਼ਨ। href attribute ਵਿੱਚ ਇੱਕ ਅਸਲੀ ਪਤਾ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ:
<a href="/docs">Documentation</a>
ਬੱਸ ਇੰਨਾ ਹੀ। ਜੇਕਰ ਉਪਭੋਗਤਾ ਕਿਤੇ ਜਾ ਰਿਹਾ ਹੈ, ਤਾਂ ਲਿੰਕ ਦੀ ਵਰਤੋਂ ਕਰੋ।
ਜਦੋਂ ਮੌਜੂਦਾ ਪੇਜ 'ਤੇ ਕੁਝ ਹੁੰਦਾ ਹੈ, ਤਾਂ <button\> ਦੀ ਵਰਤੋਂ ਕਰੋ। Buttons ਇਹਨਾਂ ਵਰਗੀਆਂ ਕਾਰਵਾਈਆਂ (actions) ਲਈ ਹੁੰਦੇ ਹਨ ਜਿਵੇਂ ਕਿ:
- ਮੋਡਲ (modal) ਖੋਲ੍ਹਣਾ
- ਫਾਰਮ ਸਬਮਿਟ ਕਰਨਾ
- ਸੈਟਿੰਗਾਂ ਸੇਵ ਕਰਨਾ
- ਮੀਨੂ ਟੌਗਲ ਕਰਨਾ
ਲਿੰਕ ਮੰਜ਼ਿਲਾਂ ਲਈ ਹੁੰਦੇ ਹਨ। Buttons ਕਾਰਵਾਈਆਂ ਲਈ ਹੁੰਦੇ ਹਨ। ਦੋਵਾਂ ਨੂੰ ਮਿਲਾਉਣ ਨਾਲ ਤੁਹਾਡਾ ਇੰਟਰਫੇਸ ਉਲਝਣ ਭਰਿਆ ਹੋ ਜਾਂਦਾ ਹੈ ਅਤੇ ਉਪਭੋਗਤਾ ਦੀਆਂ ਉਮੀਦਾਂ ਟੁੱਟ ਜਾਂਦੀਆਂ ਹਨ।
ਬ੍ਰਾਊਜ਼ਰ ਨੂੰ ਆਪਣਾ ਕੰਮ ਕਰਨ ਦਿਓ
ਆਧੁਨਿਕ ਬ੍ਰਾਊਜ਼ਰ ਦਹਾਕਿਆਂ ਦੇ ਵਿਕਾਸ ਅਤੇ ਮਿਆਰੀਕਰਨ (standardization) ਦਾ ਨਤੀਜਾ ਹਨ। ਉਹ ਸੁਰੱਖਿਆ, ਹਿਸਟਰੀ, prefetching, ਅਤੇ accessibility ਨੂੰ ਤੁਹਾਡੇ ਦੁਆਰਾ ਲਿਖੇ ਗਏ JavaScript ਨਾਲੋਂ ਬਿਹਤਰ ਤਰੀਕੇ ਨਾਲ ਸੰਭਾਲਦੇ ਹਨ।
ਇੱਕ ਅਸਲੀ anchor tag ਆਪਣੇ ਆਪ ਬ੍ਰਾਊਜ਼ਰ ਹਿਸਟਰੀ ਸਟੈਕ ਵਿੱਚ ਜਾਣਕਾਰੀ ਭੇਜਦਾ ਹੈ। ਇਹ native context menu ਦੇ ਨਾਲ ਕੰਮ ਕਰਦਾ ਹੈ। ਜਦੋਂ ਉਪਭੋਗਤਾ ਇਸ ਉੱਤੇ hover ਕਰਦਾ ਹੈ ਜਾਂ focus ਕਰਦਾ ਹੈ, ਤਾਂ ਇਹ ਬ੍ਰਾਊਜ਼ਰ ਦੇ built-in prefetching algorithms ਵਿੱਚ ਹਿੱਸਾ ਲੈਂਦਾ ਹੈ, ਜਿਸ ਨਾਲ ਤੁਹਾਡੀ ਐਪ ਬਿਨਾਂ ਕੋਈ ਕੋਡ ਲਿਖੇ ਤੇਜ਼ ਮਹਿਸੂਸ ਹੁੰਦੀ ਹੈ। ਇਹ ਲਿੰਕ ਖੋਲ੍ਹਣ ਲਈ ਉਪਭੋਗਤਾ ਦੀਆਂ ਪਸੰਦਾਂ ਦਾ ਸਤਿਕਾਰ ਕਰਦਾ ਹੈ। ਇਹ password managers, translation tools, ਅਤੇ reader modes ਦੇ ਨਾਲ ਮਿਲ ਕੇ ਕੰਮ ਕਰਦਾ ਹੈ।
ਜਦੋਂ ਤੁਸੀਂ ਇਸਦੀ ਜਗ੍ਹਾ JavaScript navigation function ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁਸੀਂ ਇਹ ਸਾਰੀਆਂ ਸਹੂਲਤਾਂ ਗੁਆ ਦਿੰਦੇ ਹੋ। ਤੁਸੀਂ ਸਿਰਫ਼ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਹੀ ਨਹੀਂ ਗੁਆ ਰਹੇ; ਤੁਸੀਂ ਉਪਭੋਗਤਾਵਾਂ ਨੂੰ ਉਹਨਾਂ ਆਦਤਾਂ ਨੂੰ ਛੱਡਣ ਲਈ ਮਜਬੂਰ ਕਰ ਰਹੇ ਹੋ ਜੋ ਉਹਨਾਂ ਨੇ ਇੰਟਰਨੈਟ ਦੀ ਹਰ ਹੋਰ ਸਾਈਟ 'ਤੇ ਬਣਾਈਆਂ ਹਨ। ਇਹ ਕੋਈ ਤਕਨੀਕੀ ਫੈਸਲਾ ਨਹੀਂ ਹੈ। ਇਹ ਇੱਕ ਮਾੜਾ (hostile) user experience ਹੈ।
ਚੈੱਕ ਕਰੋ ਕਿ ਤੁਹਾਡਾ Framework ਅਸਲ ਵਿੱਚ ਕੀ ਰੈਂਡਰ (renders) ਕਰਦਾ ਹੈ
React Router, Vue Router, Next.js Link components, SvelteKit। ਇਹ ਟੂਲ client-side routing ਨੂੰ ਬਹੁਤ ਆਸਾਨ ਬਣਾ ਦਿੰਦੇ ਹਨ। ਪਰ abstraction ਗਲਤੀਆਂ ਨੂੰ ਜਨਮ ਦਿੰਦਾ ਹੈ।
ਆਪਣੇ DOM ਦੀ ਜਾਂਚ ਕਰੋ। ਬ੍ਰਾਊਜ਼ਰ ਦੇ developer tools ਖੋਲ੍ਹੋ ਅਤੇ ਉਹਨਾਂ elements ਨੂੰ ਦੇਖੋ ਜੋ ਤੁਹਾਡਾ framework ਪੈਦਾ ਕਰਦਾ ਹੈ। ਇੱਕ <Link> component ਨੂੰ ਅੰਤਿਮ HTML ਵਿੱਚ ਇੱਕ ਵੈਧ (valid) href attribute ਦੇ ਨਾਲ ਅਸਲੀ <a\> ਟੈਗ ਵਜੋਂ ਰੈਂਡਰ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ
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
