arrow-down

Asset Library

Contents

Introduction

A simple solution to serving static assets for your Enonic application. Generates unique fingerprint URLs and sets immutable cache headers for CDN/edge and client caching. Create URLs to your assets with bundled

To host a static webapp, or for more fine-grained control over static assets, check out lib-static instead.

Usage

  1. Place your asset files in your project’s src/main/resources/assets/ folder

  2. Add a dependency to your build.gradle file:

    dependencies {
      include "com.enonic.lib:lib-asset:${libVersion}"
    }
  3. Import and use it in your controller:

    JavaScript

    var assetLib = require('/lib/enonic/asset');
    var url = assetLib.assetUrl({path: 'path/to/asset.ext'});

    TypeScript

    import {assetUrl} from '/lib/enonic/asset';
    const url = assetUrl({path: 'path/to/asset.ext'});

Configuration

The library may optionally be tuned by addding a config file. Below is a sample config with default values:

src/main/resources/com.enonic.lib.asset.json
{
  "root": "/assets", (1)
  "cacheControl": "public, max-age=31536000, immutable", (2)
  "staticCompress": true <3>,
  "cacheBust": true (4)
}
1 The folder in your app where the static files will be placed - relative to /src/main/resources

Files plaved in this folder will be publicly available

2 Cache-Control header value to be sent with 304 and 200 responses.
In XP dev mode Cache-Control header is always set to private, no-store.
3 For requests with accept-encoding br or gzip, library will look for, and serve a compressed version of the requested asset if it exists.
Pre-compressed file must have a .gzip or .br extension after the regular filename for this to work. I.e. my.css.br
4 Optionally disable application fingerprinting. This is handy if all assets contain fingerprints in their filenames.

Create a function generate the actual URLs to your fingerprinted assets. This is typically done by using a manifest file.

When disabling cacheBust for assets without fingerprints in their names, make sure to configure a proper cacheControl header to prevent cache-pollution. For instance it could be set to public, max-age=10, s-maxage=3600, stale-while-revalidate=50 to cache assets in browsers for 10 seconds and revalidate asynchronously.

Asset service

Url

The Asset library bundles a service that will handle the actual serving of assets. A service URL may look something like this: /_/service/{app-name}/asset/{app-fingerprint}/path/to/asset.ext

If Cache Busting is disabled (cacheBust: false), the URL will look like this /_/service/{app-name}/asset/path/to/asset.ext

In case of a mismatched fingerprint, the service will still responds with the asset contents and 200 code. But with a Cache-Control: private, no-store header. This prevents cache-pollution and makes website rendering more resilient to app redeployments especially in development when app fingerprint changes rapidly.

Etag

Service calculates and caches ETag for each requested asset. Cache is cleared on application restart. ETag is used to respond with 304 Not Modified for conditional requests.

In XP dev mode ETags are not generated or cached.
ETag is useful even if Cache-Control contains immutable directive. CDNs and Chrome browser ignore immutable.

API

The library exposes the following API:

assetUrl function generates a URL pointing to a static file.

Parameters

Name Type Description

params

object

Input parameters

Properties
Name Type Attributes Default Description

path

string

Path to the asset

type

string

<optional>

server

URL type. Either server (server-relative URL) or absolute

params

object

<optional>

Custom parameters to append to the url

Returns

string : The generated URL.

Example

JavaScript

const url = assetLib.assetUrl({
  path: 'styles/main.css'
});

TypeScript

const url = assetUrl({
  path: 'styles/main.css'
});

Migrating from lib-portal

Lib-asset replaces the asset hosting feature that has been part of XP core. As of XP 7.15, this feature will be deprecated, and developers should migrate to lib-asset (or lib-static) instead

Follow the steps below to migrate from the native asset handling to lib-asset.

  1. Add lib-asset dependency to your build.gradle file.

  2. Change the imports of assetUrl from /lib/xp/portal to /lib/enonic/asset.

  3. If you have used portal.assetUrl directly within Thymeleaf templates. Migrate by passing the assetUrlBase from your controller instead. See example below:

Thymeleaf migration

If you are using Thymeleaf templating, follow this practical example of how to migrate.

Controller
From
import {render} from '/lib/thymeleaf';

const VIEW = resolve('./thymeleaf-template.html');

export function get() {
  const model = {};
  return {
    body: render(VIEW, model)
  };
}
To
import {render} from '/lib/thymeleaf';
import {assetUrl} from '/lib/enonic/asset';

const VIEW = resolve('./thymeleaf-template.html');

export function get() {
  const model = {
    assetUrlBase: assetUrl({path: ''})
  };
  return {
    body: render(VIEW, model)
  };
}
Thymeleaf template
From
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <link th:href="${portal.assetUrl({'_path=styles.css'})}" rel="stylesheet" type="text/css"/>
  </head>
  <body>
  </body>
</html>
To
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <link th:href="${assetUrlBase} + '/styles.css'" rel="stylesheet" type="text/css"/>
  </head>
  <body>
  </body>
</html>
The legacy portalLib.assetUrl also supported an optional, but extremely rarely used application parameter. This parameter is not supported by lib-asset, as the URLs will always be relative to the current application.

Contents

Contents

AI-powered search

Juke AI