arrow-down
  1. Intro
  2. Usage
  3. API

Usage and examples

Contents

Introduction

There are multiple ways of deploying and using lib-static in your application. Below we expore the most common approaches. This includes how you may set up lib-static to service different files, using different cache headers.

Common

Follow these initial steps to get started, they are common for all the examples below:

  1. Use an existing Enonic app, or create a new one with the following command:

    enonic sandbox create static_tutorial -t essentials -f
    enonic create com.example.static -r starter-ts
  2. Add the lib-static dependency with a single line

    build.gradle
    dependencies {
      include "com.enonic.lib:lib-static:${libVersion}"
    }
    Replace ${libVersion} with the desired version of lib-static.

You can now move on to the various examples below:

Service example

This demonstrates how to serve assets using a http service.

This example showcases:

  • Serving assets from the default static folder

  • Overriding "immutable" default cache headers

  • Disabling serving of index.html files

  1. Start by adding a service to your app.

    /src/main/resources/services/myStatic/myStatic.ts
    import {
      RESPONSE_CACHE_CONTROL,
      requestHandler,
    } from '/lib/enonic/static';
    import Router from '/lib/router';
    
    const router = Router();
    router.all('{path:.*}', (request) => {
      return requestHandler(
        request,
        {
          cacheControl: () => RESPONSE_CACHE_CONTROL.SAFE, (1)
          index: false, (2)
        }
      );
    });
    
    export const all = (request) => router.dispatch(request);
    1 As the files are not hashed, override the default immutable cache header
    2 Disable serving of index.html files
  2. Place a folder and stylesheet in the app:

    /src/main/resources/static/css/style.css
    body {
      color: mediumblue;
    }
    /src/main/resources/static/ is the default location where lib static will look for the files
  3. Add a page controller that links to the stylesheet.

    /src/main/resources/site/pages/dynamic/dynamic.ts
    import {serviceUrl} from '/lib/xp/portal';
    
    // Static URL helper function
    const myStaticUrl = (path: string) => `${serviceUrl({service: 'myStatic'})}/${path}`;
    
    export const get = () => {
      return {
        body: `<!DOCTYPE html>
    <html>
    <head>
        <title>Dynamic Page with static assets</title>
        <link rel="stylesheet" href="${myStaticUrl('css/style.css')}"/>
    </head>
    <body>
        <main>
            <h1>Dynamic Page with static assets</h1>
            <p>All text on this page shoule be mediumblue.</p>
        </main>
    </body>
    </html>`,
        status: 200
      };
    };
  4. Create a site with a page using this controller, you should instantly see the result.

Site mapping example

Developers using site engine may want to serve the assets from a pretty URL, rather than a service endpoint.

This example demonstrates

  • use of relativeMappedPath

  • using a custom static folder location

  1. Create a controller that will serve the files:

    site/controllers/myController/myController.ts
    import {
      mappedRelativePath,
      requestHandler,
    } from '/lib/enonic/static';
    import Router from '/lib/router';
    
    const router = Router();
    router.get('{path:.*}', (request) => {
      log.info('mapped get request:%s', JSON.stringify(request, null, 4));
      return requestHandler(
        request,
        {
          relativePath: mappedRelativePath('mymapping'), (1)
          root: '/site/controllers/myController/files', (2)
        }
      );
    });
    
    export const all = (request) => router.dispatch(request);
    1 relativeMappedPath must match the mapping in site.xml below
    2 Defines a custom location where the controller will look for static files
  2. Define the mapping in your site.xml file.

    site/site.xml
    <site>
      <mappings>
        <mapping controller="/site/controllers/myController/myController.js" order="1">
          <pattern>/mymapping(/.*)?</pattern>
        </mapping>
      </mappings>
    </site>
  3. Add a file to the static files folder. In this case we place the files together with the controller:

    site/controllers/myController/files/css/styles.css
    body {
        color: green;
    }
  4. Build, deploy and add the application to a site. The files will be served from site-relative mapping path (in this case /mymapping/css/styles.css).

Webapp example

Lib static is also capable of acting like a webserver, serving html-files. In this example we use XP’s /webapp feature to do the job. To make the example as realistic as possible, we use a React SPA created with Vite.

Read more about XP webapps

This example demonstrates advanced use-cases like:

  • Custom Cache control handling

  • Fallback handling to SPA file for 404

  • Custom static folder location

  1. Create a new React app using Vite

    npm create vite@latest my-app-name -- --template react-ts
    cd my-app-name
  2. Replace the default App.tsx file with this:

    /src/vite/App.tsx
    import './App.css'
    import { BrowserRouter, Link, Route, Routes } from "react-router-dom";
    
    function App() {
      return (
          <BrowserRouter basename='/webapp/com.example.static'> {/* <1> */}
            <Routes>
              <Route path="/" element={<Link to="/bookmarkable">Bookmarkable</Link>}/>
              <Route path="/bookmarkable" element={<Link to="/">Home</Link>}/>
              <Route path="*" element={<div>
                <h1>404</h1>
                <Link to="/">Go home</Link>
              </div>}/>
            </Routes>
          </BrowserRouter>
      )
    }
    
    export default App
    You may serve the webapp from any context path (and domain) using vHosts. Make sure the baseUrl in your React app is compliant with the deployment.
  3. From the React app folder, build the static webapp:

    npm install
    npm run build
  4. Copy the static webapp files from the React app dist/ folder into your Enonic app. In this case src/main/resources/webapp/files/

  5. In the Enonic app, create a webapp controller that will serve the SPA

    src/main/resources/webapp/webapp.ts
    import {
      RESPONSE_CACHE_CONTROL,
      defaultCacheControl,
      requestHandler,
      spaNotFoundHandler,
    } from '/lib/enonic/static';
    import Router from '/lib/router';
    
    const router = Router();
    router.get('{path:.*}', (request) => requestHandler(
      request,
      {
        // Override the defaultCacheControl
            contentType,
            path,
            resource,
        }) => {
          // The "webapp/files/vite.svg" file has no contentHash
          if (path.startsWith('/vite.svg')) {
            return RESPONSE_CACHE_CONTROL.SAFE;
          }
          // fall back to defaultCacheControl for all other assets.
          return defaultCacheControl({
            contentType,
            path,
            resource,
          });
        },
        // Fallback to SPA index.html when asset not found
        notFound: spaNotFoundHandler,
        root: '/webapp/files',
      }
    ));
    
    export const all = (request) => router.dispatch(request);
  6. Build and deploy the Enonic app containing the SPA, you should see the result by visiting http://localhost:8080/webapp/com.example.static


Contents

Contents

AI-powered search

Juke AI