Putting that SVG defs block at the top of the document definitely works. It has some advantages too, like the fact that no HTTP request needs to be make, all the information for drawing the graphics is right on the page. But, it has some disadvantages too. All that information needs to be parsed by the browser on each page, from the document. It's not a separate document that might already be cached by the client, like other assets might be. And speaking of cache, if your site caches HTML (typically a good idea), you could consider this "page cache bloat" because every single cached page includes this large repetitive block of code - not a very efficient use of server cache.
The good news is we can move that SVG defs block out to an external file, and use it just like we would an image or any other asset.
When we use it then, the file path would be in the attribute, like this:
<svg class="icon-book"> <use xlink:href="/path/to/imgs/svg-defs.svg#icon-book"></use> </svg>
Important to know: Cross-domain restrictions are tough on this. Even CORS headers won't help you in my experience. So no CDN's (can't even play on CodePen, and definitely can't play at a file:// URL).
Another important thing to know: You definitely need to xmlns attribute for this to work. As in, your SVG defs block should start with:
I was under the impression that you didn't need that in an HTML5 document (in much the same way you don't need types on
<script>s), but perhaps because this file isn't within the confines of an HTML5 document anymore (it's being externally referenced), you need it.
For that reason, the demo for this is here.
Equally important to know: No version of IE supports this (up to 11 at the time of this publishing). But there is a way to get it to work, by essentially Ajaxing in the bit of SVG you need and inserting it where the
<use> would be, making it kinda "normal" inline SVG that is supported. It takes us a hot minute to get this working and tested in Internet Explorer using BrowserStack, but ultimately we get it.