Skip to main content

Podium context

The purpose of the Podium Context is to give a podlet access to information about each incoming HTTP request so that it can tailor its response accordingly.

More specifically, a podlet can use the context to:

  • Construct URLs specific to the layout where the request came from.
  • Respond differently depending on locale eg. en-US or no-NO.
  • Respond differently depending on what type of device environment was used to make the request eg. mobile or desktop.
  • Respond differently depending on whether the layout is in debug mode or not.

The role of the layout

The context is created in the layout for each request. The @podium/layout module includes a set of default context parsers, which are functions that read the incoming request and return some kind of value that is placed on the context.

You must manually pass the context object on to podlets in the call to .fetch(ctx). The context object is serialized as HTTP headers which are then deserialized to a context object in the podlet.

app.get(layout.pathname(), (req, res) => {
const incoming = res.locals.podium;
const content = await myPodlet.fetch(incoming);
});

Change the default context parsers

The included context parsers have a default configuration which should cover most use cases. It is possible to overwrite default configuration when constructing a layout.

const layout = new Layout({
context: {
debug: {
enabled: true,
},
},
});

See the @podium/layout reference for more detailed documentation regarding configuring the default context parsers.

Add custom context parsers

You can extend the Podium context by registering additional parsers.

import CustomContext from "my-custom-context-parser";

layout.context.register("my-custom-context", new CustomContext());

In the example above a new camelCased value myCustomContext will be available on the Podium context to podlets you fetch.

Default context variables

All requests made by @podium/layout include these variables on the context:

NameHeader NameContext NameDescription
Debugpodium-debugdebugA boolean value informing the podlet whether the layout is in debug mode or not. Defaults to false
Localepodium-localelocaleA bcp47 compliant locale string with locale information from the layout. Defaults to en-US
Device Typepodium-device-typedeviceTypeA guess (based on user-agent) as to the device type of the browser requesting the page from a layout server. Possible values are desktop, tablet and mobile. Defaults to desktop
Mount Originpodium-mount-originmountOriginURL origin of the inbound request to the layout server. For example, if the layout server is serving requests on the domain http://www.foo.com this value will be http://www.foo.com
Mount Pathnamepodium-mount-pathnamemountPathnameURL path to where a layout is mounted in an HTTP server. This value is the same as the layout's pathname option. For example, if the layout server has mounted a layout on the pathname /bar (http://www.foo.com/bar) this value will be /bar.
Public Pathnamepodium-public-pathnamepublicPathnameURL path to where a layout server has mounted a proxy in order to proxy public traffic to a podlet. The full public pathname is built up by joining together the value of Mount Pathname with a prefix value. The prefix value is there to define a namespace to isolate the proxy from other HTTP routes defined under the same mount pathname. The default prefix value is podium-resource. For example, if the layout server has mounted a layout on the pathname /bar (http://www.foo.com/bar) this value will be /bar/podium-resource/.

Read context values in a podlet

The @podium/podlet module converts context HTTP headers into keys and values and places them on the HTTP response object at res.locals.podium.context.

As shown in the table above, context names are converted from kebab case to camel case and the Podium prefix is removed. The podium-mount-origin header is named mountOrigin on res.locals.podium.context.

app.get(podlet.content(), (req, res) => {
// res.locals.podium.context.mountOrigin
});

Construct public URLs

One thing the context is often used for is to construct URLs that need to include the public URL of the layout.

In a podlet, the origin of a layout server can be found at res.locals.podium.context.mountOrigin and the pathname to the layout server can be found at res.locals.podium.context.mountPathname.

These adher to the WHATWG URL spec so you can easily compose full URLs by using the URL module in Node.js.

Example: using the URL module to construct urls from context values

import { URL } from "url";
const { mountOrigin, mountPathname } = res.locals.podium.context;
const url = new URL(mountPathname, mountOrigin);
// url.href => <mountOrigin>/<mountPathname>
// eg. http://localhost:3040/cats

Example: using the URL module to construct proxy urls from context values

import { URL } from "url";
const { mountOrigin, publicPathname } = res.locals.podium.context;
const url = new URL(publicPathname, mountOrigin);
// url.href => <mountOrigin>/<publicPathname>
// eg. http://localhost:3040/cats/podium-resource

Developing a podlet without a layout

In a production environment the layout is responsible for providing the context. To simplify development of podlets there's a development mode which includes some sensible default values.

const podlet = new Podlet({
/* ... */
development: true, // This should be turned off in production
});

You can change the default context values if you'd like by calling podlet.defaults().

podlet.defaults({
locale: "nb-NO",
});
tip

Get the browser extension and the accompanying dev-tool middleware to make it possible to change these defaults without changing code and restarting your server.