Recently had a need to create an email template in Salesforce.com for Marketing that included about 10 images. The recommended method for storing those documents is to put them in ‘Documents’ and make sure they are ‘Externally Available’. Not files…or Content…Documents. See what I did there? Called out that there are three different file/CMS stores in Salesforce.com. Three. That’s crazy…but that is how it has been for many years now.
So thinking outside the box with my recent experience with Bootstrap and Static Resources (which would technically be a forth storage technology!) I thought maybe I would zip those files up and just call them using the following:
<apex:image value=”https://cs20.salesforce.com{!URLFOR($Resource.ME000135, ‘images/home.jpg’)}” width=”75″ height=”75″ />
Why take this approach? The ‘Documents’ container is not really designed for file management or organization or tagging or really anything other than dumping files in a folder. Works great in the test lab where you might have a couple dozen files but in the real world where a couple email templates later you have 100’s of files with no real way to manage and more importantly TEST, it quickly becomes a tangled mess. The idea of zipping all those graphic files in an archive so that you can refer to them in code seemed like a lot simpler and easier to manage.
Well that dream was busted when testing proved that I could not get the images to come across in email. Here is why:
Why images stored as static resources cannot be seen in emails sent using VF email templates?
Just in case that article goes missing (which sadly happens a lot in knowledge databases these days after the yearly UI/UX redesign/refresh):
The reason why the image doesn’t show up in the email is because value=”{!$Resource.myResourceImage}” generates a relative URL from which the image is rendered (i.e. “/resource/1312483024000/logo”). This URL is accessible only for authenticated platform users.
Also, when we store images as static resources, the field “Cache Control” = “Public” specifies that the static resource data cached on the Salesforce server be shared **with other users in your organization** for faster load times. Setting it “Public” will not allow it to be accessible outside salesforce Org.
To solve this problem, images should be stored in documents and with “Externally Available Image” checked. The image will be available by using the following markup:
<apex:image id=”theImage” value=”https://c.<instance>.content.force.com/servlet/servlet.ImageServer?id=<document_id>&oid=<organization_id>” width=”200″ height=”200″/>