I’ve been struggling with the idea of remote loading SVGs. There are a lot of problems with this, mostly due to the DOM structure of how your browser loads an SVG file.
What’s an SVG and the DOM?
Scalable Vector Graphics, or SVG, is a special XML file. It’s generally used like an image, like JPG or PNG, and contains vector graphics. This makes it smaller than PNGs and scalable without resolution loss. Pretty nifty for icons. In fact, better than my beloved Fonts.
Making this worse, if you use
<img> tags to embed the SVG, many browsers will execute the code. Even today. Yeah… Not really a good thing.
Embedding SVGs externally has a cost
If you want to include an SVG file in your web page, you can use that dangerous
<img> tag, but you can also use
<svg> code right in the document. The problem there is that requires the SVG to essentially be pasted into the code. For PHP, you can use code like
file_get_contents() (which doesn’t always work remotely) or if you’re WordPressy,
The catch there? They’re slow if you list, oh, 69 images on a page. You can, of course, use
<img> tags and that loads the SVG remotely, perfectly happily. If you’re sure about your SVGs, this is okay. You’re just going to lose one big, super big feature about SVGs.
You can’t use CSS to edit them (color, resizing, etc) anymore.
And that, my friends, is a big problem.
You saw that but coming, right?
It didn’t work. Because of CORS.
What the heck is CORS?
Cross Origin Resource Sharing, CORS, is that magical thing that says “Hey you can’t run this resource remotely, yo!” Generally it’s related to Fonts (if you’ve ever tried to embed your own fonts from your own servers, you’d have run into this). I happened to hit it on SVGs, and basically the server where I host the icons wasn’t allowing my servers (local or otherwise) to load the icons.
Thankfully! I use DreamObjects, and you can totally set up CORS on DreamObjects. You can do it on Amazon S3, and I think all the various CEPH-esque services let you.
The catch here (hah you saw that coming, right?) is that not all clients let you do it. Lucky for me, I have s3cmd on my laptop (you should too if you’re going to work with S3 type services – it’ll make your life easier). Installing is easy, and you just have to make a
.s3cfg file (DreamHost has some instructions).
Once that’s set up, you can make your rules file like this:
<CORSConfiguration> <CORSRule> <ID>Allow My Icons</ID> <AllowedOrigin>https://www.example.com</AllowedOrigin> <AllowedOrigin>http://www.example.com</AllowedOrigin> <AllowedOrigin>https://example.com</AllowedOrigin> <AllowedOrigin>http://example.com</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedMethod>HEAD</AllowedMethod> <AllowedHeader>Content-*</AllowedHeader> <AllowedHeader>Host</AllowedHeader> <ExposeHeader>ETag</ExposeHeader> <MaxAgeSeconds>86400</MaxAgeSeconds> </CORSRule> </CORSConfiguration>
and then you can set (and check) your CORS:
ipstenu@Uhura:~$ s3cmd setcors Development/example.com/cors-rules.xml s3://my-icons ipstenu@Uhura:~$ s3cmd info s3://my-icons s3://my-icons/ (bucket): Location: us-west-1 Payer: BucketOwner Expiration Rule: none Policy: none CORS: <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><CORSRule><ID>Allow My Icons</ID><AllowedMethod>GET</AllowedMethod><AllowedMethod>HEAD</AllowedMethod><AllowedOrigin>http://example.com</AllowedOrigin><AllowedOrigin>http://example.com </AllowedOrigin><AllowedOrigin>https://www.example.com </AllowedOrigin><AllowedOrigin>https://www.example.com </AllowedOrigin><AllowedHeader>Content-*</AllowedHeader><AllowedHeader>Host</AllowedHeader><MaxAgeSeconds>86400</MaxAgeSeconds><ExposeHeader>ETag</ExposeHeader></CORSRule></CORSConfiguration> ACL: lezpress: FULL_CONTROL
And now you can embed your SVGs remotely.