Nobody wants to see %20, or other strange encodings in their URLs. Some say they are not good for SEO. Some say your users will hate you for it. All I know is that they look ugly. And you will have them in your URLs if you your item names contain spaces.
Of course you could train your users not to create items with spaces, but that renders the
$name tokens a bit useless, since typically you do want the spaces in the field values.
Sitecore has provided a built-in way of avoiding this problem for a long time. It's called Encode Name Replacements and you define it in the web.config (obviously with include files). The idea is very simple you declare pairs of symbols like:
<encodeNameReplacements> <replace mode="on" find=" " replaceWith="-" /> </encodeNameReplacements>
so that when Sitecore is constructing a URL if it finds a space it will replace it with a hyphen. And of course, conversely, when mapping a URL to an item if it finds a hyphen it will make it into a space when looking for the item.
This setting also works if you are using the Display Name for your URLs (because you want to be able to localize them).
This would be the simplest solution, except it does not always work consistently across Sitecore versions. I have done a quick trip down memory lane and this is what I have found out.
Version 7.0 - Encode name replacements only works for items, not for media items which maintain the original name. If an item has the replacement character in its name (say the hyphen if you are replacing spaces for hyphens), then that item will always return a 404 as Sitecore looks for an item with a space.
Version 7.0 rev 140408 (aka 7.0 sp1 and 7.0 Update-5) - fixes the issue so items are found even if they contain the replacement character. However it is not working correctly if using Display Names. Media items still ignore all encode name replacements.
Version 7.1 rev. 140905 (7.1 Update-3) - Media items now follow the encode name replacemenents. However if they contain the replacement character in their name, Sitecore cannot find them.
8.0 rev.150427 (8.0 Update-3) - fixed issue with media items, they will follow replacements too. Also Display Names with the replacement character are treated correctly.
8.1 and 7.2 rev 151021 (Update-5) - The replacement " "-> "-" comes already configured as default.
So according to the above, if you are on a 7.x version you should update to 7.2 Update 5, which fixes all the issues, and if you are on 8.x anything above Update 3 should be OK.
If you must stay on other versions the easiest solution is to define the replacement character as an illegal one. For example if you have
<replace mode="on" find=" " replaceWith="-" /> then add the hyphen to
<setting name="InvalidItemNameChars" value="\/:?"<>|-" />. This does not help if you are using Display Names for URLs, but then you may have some validation to ensure they don't contain illegal characters.
Of course over the years this has been solved in other ways without using Encode Name Replacements. You could have an event that renames the item, you could have validation or even create some custom actions and use rules. But now that it comes as a default setting in the newest versions, I think Encode Name Replacements is the way to go.