Skip to main content Skip to secondary navigation Accessibility Feedback

Handling Chinese and Cyrillic character hash and href values in JavaScript

Last week, I got a bug report on Smooth Scroll that content with Chinese and Cyrillic characters in the ID weren’t working in Safari and Firefox. The problem seemed to extend to any valid, non-ASCII characters.

I eventually discovered that when calling the hash or href of an element in JavaScript, Chrome handles non-ASCII characters quite differently (I’d argue, more correctly) than Firefox or Safari do.

Hey there! If you find vanilla JS difficult, I've written a step-by-step training guide to help you master vanilla JavaScript. Start learning today →

In a click listener, I have this code:

// Get the clicked anchor link's hash value
var hash = event.target.hash;

If this is the clicked link…

<a href="#中文">Click Me!</a>

Chrome returns #中文, while Safari and Firefox return an encoded version of that, #%E4%B8%AD%E6%96%87. (I didn’t have access to IE or Edge to test.)

The fix to this was actually really simple. Decode the hash using decodeURIComponent().

// Get the clicked anchor link's hash value
var hash = decodeURIComponent( event.target.hash );

However, some elements have characters that decodeURIComponent() doesn’t like, so you have to do some error catching.

// Get the clicked anchor link's hash value
var hash;
try {
    hash = decodeURIComponent( event.target.hash );
} catch(e) {
    hash = event.target.hash;
}

Problem solved!

If you liked this article, you might also enjoy The Vanilla JS Guidebook, a step-by-step training guide to help you master vanilla JavaScript. Start learning today →

Have any questions or comments about this post? Email me at chris@gomakethings.com or contact me on Twitter at @ChrisFerdinandi.

Get the Spare Parts Newsletter

Every week, I send out a short email packed with web development resources and interesting stuff from around the web.