Title: Serve static content
Author: WordPress VIP Documentation
Published: January 6, 2022
Last modified: February 29, 2024

---

 1. [Node.js on VIP](https://docs.wpvip.com/node-js/)
 2. Serve static content

#  Serve static content

Static content served from a [Node.js environment](https://docs.wpvip.com/node-js/)
can have faster uncached response times compared to static content served by a WordPress
environment (e.g. [serving an ads.txt file](https://docs.wpvip.com/wordpress-skeleton/serve-static-content-wp/))
and requires less custom code. Static content that is is served using the example
method below will be served from the same domain as the Node.js environment.

A [code example demonstrating a method for serving static files](https://github.com/Automattic/vip-go-node-skeleton/tree/master/examples/static)
from a Node.js environment is included for reference in the [vip-go-node-skeleton repository](https://github.com/Automattic/vip-go-node-skeleton/).
This code example uses [Express](https://expressjs.com/), a web framework for Node.
js. The Express [built-in static middleware](https://expressjs.com/en/starter/static-files.html)
makes it possible to serve the static content and satisfies [the requirements of the VIP platform](https://docs.wpvip.com/vip-platform/node-js/#h-requirements).

## Importing the Express middleware

Express must be imported and the middleware created. To do this, define the `app`
constant to reference an instance of Express, and identify the port to use (this
defaults to `3000` in local development).

_[Location of this code snippet in the example repository.](https://github.com/Automattic/vip-go-node-skeleton/blob/d8e7af4c7a6b5c8a3329014dca78f461628ca7e3/examples/static/src/index.js#L5-L11)_

    ```lang-php
    const express = require( 'express' );
    const path = require( 'path' );

    const app = express();

    const PORT = process.env.PORT || 3000;
    const BASEURL = process.env.BASEURL || 'http://localhost';
    ```

## Handling the cache healthcheck endpoint

All Node.js applications must implement the [cache health check endpoint](https://docs.wpvip.com/node-js/health-checks/)
using application code.

_[Location of this code snippet in the example repository.](https://github.com/Automattic/vip-go-node-skeleton/blob/d8e7af4c7a6b5c8a3329014dca78f461628ca7e3/examples/static/src/index.js#L28-L30)_

    ```lang-php
    app.get( '/cache-healthcheck', function (req, res) {
    	res.status( 200 ).send( 'Ok' );
    });
    ```

A Node.js environment can handle a mixture of static content and dynamic routes.
Each URL is processed in the order defined in the code, so the example code above
will respond to `/cache-healthcheck?` with an “Ok” even if there’s a matching file
in the public directory, which is essential to ensure that the cache healthcheck
functionality is always working.

## Serving the static content

The directory from which to serve static assets must be specified. For this example,
static assets should be placed in [the `public` directory](https://github.com/Automattic/vip-go-node-skeleton/tree/master/examples/static/src/public),
and they will be accessed with a URL relative to a root path.

_[Location of this code snippet in the example repository.](https://github.com/Automattic/vip-go-node-skeleton/blob/b3d928496aa5f27f51a26dbc4b949f51b090fba2/examples/static/src/index.js#L35)_

    ```lang-php
    app.use( '/', express.static( path.join( __dirname, 'public') ) );
    ```

The `app.use` statement can be wrapped with a conditional. For example, a conditional
that enables a switch between two different sets of static content based on the 
time and date, that “lifts the curtain” on a microsite on demand.

Express should serve a `404` for any invalid static URLs. This behavior, and others,
[can be customized](https://expressjs.com/en/4x/api.html#express.static).

For more information about static assets directories, refer to the [Express project website](https://expressjs.com/en/starter/static-files.html).

## Defining the port

`app.listen` is a standard requirement for the app to handle all incoming requests
by listening on the defined `PORT`.

_[Location of this code snippet in the example repository.](https://github.com/Automattic/vip-go-node-skeleton/blob/b3d928496aa5f27f51a26dbc4b949f51b090fba2/examples/static/src/index.js#L37-L39)_

    ```lang-php
    app.listen( PORT, () => {
    	console.log( `Static example listening on ${BASEURL}:${PORT}` );
    })
    ```

## Defining `build` and `start`

Including the `build` and `start` commands in the `package.json` file are a [requirement for a Node.js app to run on VIP’s infrastructure](https://docs.wpvip.com/node-js/).

_[Location of this code snippet in the example repository.](https://github.com/Automattic/vip-go-node-skeleton/blob/master/examples/static/package.json)_

package.json

    ```lang-js
    "scripts": {
        "test": "npx @automattic/vip-go-preflight-checks --verbose --wait=2000",
        "build": "echo 'No build script step configured, skipping build. For further information, refer to our documentation at https://docs.wpvip.com/node-js/#h-requirement-2-production-dependencies-and-npm-scripts'",
        "start": "node ./src/index.js"
      },
    ```

Last updated: February 29, 2024