Skip to main content
Backend scripts support import / export syntax to share functions, constants, and objects between pages. Create a “module” page with exported code, then import what you need in any other page’s backend script.

Quick example

Create a page (e.g. slug app) with shared functions:
<script scope="backend">
  export const getGreeting = function (name) {
    return 'Hello, ' + name + '!';
  };

  export function isAdmin(email) {
    return email === 'admin@mybrand.com';
  }
</script>
Import and use them in another page:
<script scope="backend">
  import { getGreeting, isAdmin } from "app";

  if (customer && customer.email) {
    setVariable('greeting', getGreeting(customer.name));
    setVariable('is_admin', isAdmin(customer.email));
  }
</script>

<h1>{{ var.greeting }}</h1>

Import specifier formats

All of these resolve to the same page slug app:
import { test } from "app";        // bare name
import { test } from "app.js";     // with .js extension
import { test } from "../app.js";  // relative path
import { test } from "./app";      // relative path
The resolution rules:
  1. The .js extension is stripped
  2. Leading ./ or ../ prefixes are stripped
  3. The remaining string is used as the page slug to look up
For nested pages, the slug path is preserved:
import { helper } from "utils/helpers";  // resolves to page slug "utils/helpers"

Named imports

Import specific exports by name:
// Module page (slug: "utils")
export const TAX_RATE = 0.08;
export function calculateTax(amount) {
  return amount * TAX_RATE;
}
export function formatCurrency(val) {
  return '$' + val.toFixed(2);
}
// Importing page
import { calculateTax, formatCurrency } from "utils";

var price = 49.99;
var tax = calculateTax(price);
setVariable('total', formatCurrency(price + tax));

Default imports

Use export default for a module’s primary export:
// Module page (slug: "config")
export default {
  siteName: 'My Store',
  supportEmail: 'help@mystore.com',
  maxItems: 10
};
// Importing page
import config from "config";

setVariable('site_name', config.siteName);
setVariable('support_email', config.supportEmail);

Multiple modules

Import from several pages in the same script:
<script scope="backend">
  import { isAdmin } from "auth";
  import { getGreeting } from "helpers";
  import config from "config";

  if (customer && isAdmin(customer.email)) {
    setVariable('greeting', getGreeting(customer.name));
    setVariable('site', config.siteName);
  }
</script>

Module pages work on their own

A page with export statements still works when visited directly — the export keywords are silently stripped before execution. This means you can add setVariable calls alongside exports for the module page’s own rendering:
<script scope="backend">
  export function getPlans() {
    return getAllProducts({ classification: 'subscription' });
  }

  // This runs when the module page is visited directly
  var plans = getPlans();
  setVariable('plan_count', plans.length);
</script>

<p>We offer {{ var.plan_count }} subscription plans.</p>
When another page imports getPlans, only the function is used — the setVariable call in the module runs inside the importing page’s context too (both scripts share the same sandbox).

Supported export syntax

SyntaxSupported
export const name = ...Yes
export let name = ...Yes
export var name = ...Yes
export function name() { ... }Yes
export async function name() { ... }Yes
export class Name { ... }Yes
export default ...Yes
export { name1, name2 }Yes

Limits

ConstraintValue
Max imports per script10
Import depth1 level (nested imports inside modules are not resolved)

Supported import shapes

Each import line must be either a default import or a named import — not both on the same line:
import { Greeter, wrap } from "app";   // named — OK
import config from "config";           // default only — OK
// import Greeter, { wrap } from "app";  // not supported — use named exports only, or split across modules
You can combine classes and functions from the same module with named imports, or import a class from one module and helpers from another. Exported functions may return nested objects, arrays of objects, or build structures from parameters — this is fully supported after inlining:
// Module
export function getPayload() {
  return { user: { name: 'Pat' }, items: [{ id: 1 }] };
}
export const config = { api: { version: 2 } };
export function merge(input) {
  return { out: { a: input.a || 0 } };
}

How it works internally

When a backend script contains import statements:
  1. Import statements are parsed and removed from the script
  2. Each module specifier is normalized to a page slug
  3. The module page’s <script scope="backend"> code is fetched
  4. export keywords are stripped from the module code, turning exports into regular declarations
  5. The module code is prepended to the importing script
  6. The combined code runs as a single script in the sandbox
This is a compile-time inline — not a runtime module loader. The imported code becomes part of the same function scope as the importing script, with full access to all sandbox globals (setVariable, session, request, etc.).