Last edit: Dec 08, 2023

Assets are files that can be served by an HTTP web server without any backend/server processing. They are usually Javascript files, stylesheets (CSS), images, documents (pdf, doc), fonts, or media (audio, video) files.

Assets directory

The directory for assets is: app/assets

The directory for assets in a module is: modules/[my_module]/public/assets

In order to correctly communicate with the platformOS engine and API, your codebase should be organized into a specific directory structure. The root directory of your project should contain the app directory, and assets should be placed into the assets directory inside app.

Although only the assets directory is required and you can put your assets there, we recommend you further organize your assets into subdirectories inside the assets directory, e.g. images, scripts for Javascript files, styles for CSS files, etc. This is also how the pos-cli init command will create the codebase.

Content Delivery Network

Assets are uploaded to a Content Delivery Network (CDN). The directory structure on the CDN corresponds to the required directory structure of your codebase, except for the beginning of the URL.


Location of the image asset in the codebase:

URL of the image asset on CDN:

URL of the image asset on your vanity domain with no CDN involved (it is slower, CDN solution is recommended):


CDN host and Instance ID are dynamic and will be specific to your instance and region

Busting browser cache

When you use the asset_url or asset_path filters, paths to files will be suffixed with an updated parameter and a number (?updated=1586975239). This number is an epoch timestamp indicating when the file was updated most recently. This is the mechanism to force the browser to use the newer version from the CDN, instead of using the locally cached version. This way you don't have to change the file name every time your content changes. You can, but you don't have to.

The updated parameter will not be added to files that do not exist, because the server doesn't know when it was last updated, since it doesn't exist.

Accessing assets

You can access assets using three different ways (that we know of):

  • relative path on the CDN - used usually in CSS files to access fonts, images

Accessing an image in app/assets/images/logo.svg from a CSS file located at app/assets/styles/app.css:

background: transparent url('../images/logo.svg') top center no-repeat;
  • asset_url liquid filter - returns absolute URL to the CDN with the updated parameter


Accessing a JavaScript file located in app/assets/scripts/app.js from a Liquid file:

<script src="{{ 'scripts/app.js' | asset_url }}"></script>

File has been found:

File does not exist:


Be careful not to use a leading / in your path when using the asset_url filter.

  • asset_path Liquid filter - returns relative path to Instance domain (no CDN, worse performance for end users) with the updated parameter


<script src="{{ 'scripts/app.js' | asset_path }}"></script>

File has been found:

File does not exist:


Be careful not to use a leading / in your path when using the asset_path filter.

Accessing assets placed in modules

Assets in modules are namespaced to not conflict with each other. They are also accessed by prefixing the path with the modules/[my_module] prefix. It does not matter whether you try to access the files from a module or not, the path to the asset is the same. Which means only location of the asset file matters, not where you write the code that references it.


File location: modules/[my_module]/public/assets/js/app.js

Asset url filter access: {{ 'modules/[my_module]/js/app.js' | asset_url }}
Asset path filter access: {{ 'modules/[my_module]/js/app.js' | asset_path }}

Removing assets

Unlikely everything else - pages, partials, layouts - assets are NOT automatically deleted during deploy. In order to remove the physical file from S3, the only way to do it is to use admin_asset_delete mutation. Please note that it is not possible to revert this operation.


We are always happy to help with any questions you may have.

contact us