I am developing some Salesforce Lightning components at the moment as while Lightning Components are great they have a major drawback in my mind. Some background first… Salesforce Lightning is our “new” component based UI based on HTML / Javascript and components are automatically mobile ready and responsive. A Lightning Component is not a single “thing” but rather a folder with stuff that is a number of files named using a predefined format. The component name is the name of the folder – e.g. MyComponent. The actual markup goes in the component file called MyComponent.cmp. Besides the markup there is the client side controller (MyComponentController.js), CSS styling (MyComponent.css) and that’s basically it. There are few more potential files but they are not important for this post. All is well described on the web. What’s not included in the component is graphics that may be used by the component.
The way graphics are added to components a either by using the sprites supplied with the Salesforce Lightning Design System (SLDS), by using custom graphics or you can use the classic icons which are supplied by Salesforce. The latter are really not ideal as do not look nice as they look old and the colors cannot be easily changed. The issue with using custom graphics or the SLDS sprites is that the resources are kept in Salesforce as static resources which is great for performance as they are automatically loaded through our CDN but they are outside the Lightning component. So now a component is no longer self contained but has dependencies to other metadata elements. To make it even worse these dependencies cannot be declared for the component that the normal dependency detection doesn’work eg. changesets will not detect the dependency. Not good…
To solve this I’ve started to use base64 encoded images as they can easily be used in img-tags and may be embedded in either markup or in JavaScript. An img-tag can use base64 instead of an image reference as below. This solves the above issue as images are now fully contained in the component code or markup so no external dependencies are required. An easy solution to a complicated problem.
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAL" />
This
On Mac (and Linux probably) getting an image as a base64 encoded image for easily done using the base64 command and I normally cut lines to 80 characters as the developer console doesn’t handle looooooong lines well. Combining with sed can add the quotes and pluses to make it easier to get it into Javascript. A little tweaking if required but it is faster.
base64 -b 80 -i ./picture1.png base64 -i Downloads/gold_star.png -b 80 | sed -e 's/^(.*)$/"1"+/'
For SLDS sprites in Lightning the approach would be to use lightning:icon, where the aura application gets extended with force:slds.
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_lightning_icon.htm
LikeLike
Of course the Salesforce Lightning Design System is Salesforce agnostic but it’s funny that the SLDS website only mention the SVG approach. I’ll have to look into using the lightning:icon tag instead of the SVG custom component as that would definitely remove the dependency on a SLDS static resource. That would be nice. The issue is however still the same for custom – non-SLDS – graphics.
LikeLike