CMS
Third party scripts

Third-Party Script Support in Shophub

Shophub supports the integration of third-party scripts, which include both JavaScript (script type) and stylesheets (link type). This allows for greater flexibility and customization on your pages.

Script Type

Scripts in Shophub are defined using the Script type. The Script type includes several properties to configure the script's behavior and scope. Below is an example of the Script type:

enum ThirdPartyScriptType {
  stylesheet = 'stylesheet',
  jsScript = 'jsScript',
}
 
type Script = {
  title: string;
  description?: string | null;
  url: string;
  type: ThirdPartyScriptType;
  pageType?: PageType | null;
  slug?: string | null;
  enabled: boolean;
  priority?: number;
  options?: ScriptOptions;
};

Script Options

The ScriptOptions type defines additional optional parameters that can be applied to scripts. These options control various attributes of the script or stylesheet, and they are applied only if they are not undefined or false. Here’s a detailed breakdown of each entry in ScriptOptions:

type ScriptOptions = {
  async?: boolean;
  defer?: boolean;
  attributionsrc?: string;
  blocking?: boolean;
  crossorigin?: Crossorigin;
  fetchpriority?: FetchPriority;
  nomodule?: boolean;
  referrerPolicy?: ReferrerPolicy;
};
async
boolean

If true, the script will be executed asynchronously as soon as it is available.

defer
boolean

If true, the script will be executed when the page has finished parsing.

attributionsrc
string

Specifies a URL for the attribution source.

blocking
boolean

If true, the script or link will block the rendering of the page until loaded.

crossorigin

Indicates the CORS setting for the script or link. Acceptable values are defined in the Crossorigin enum.

fetchpriority

Sets the priority of the resource fetch, defined in the FetchPriority enum.

nomodule
boolean

If true, the script is not to be executed in older browsers that support modules.

referrerPolicy

Controls the referrer information sent with the script or link requests, defined in the ReferrerPolicy enum.

Creating a Script

To add a new script in the backend, the following parameter are expected:

class ScriptDto {
  title: string;
  description?: string | null;
  url: string;
  type: ThirdPartyScriptType;
  pageType?: PageType | null;
  slug?: string | null;
  enabled: boolean;
  priority?: number | null;
  options?: ScriptOptionsDto;
}

Page application

Defined scripts that are enabled will automatically be injected to the applicable pages. If a page is applicable or not, is determined based on the pageType and slug.

  • pageType: Defines the type of page on which the script will be injected. If both pageType and slug are provided, the script is injected only on the specific page identified by the slug. If pageType is set but slug is null, the script is injected on all pages of that type. If both pageType and slug are null, the script is injected globally on all pages.
  • slug: Specifies the slug of the specific page where the script should be injected.

Order of execution

With the help of the priority value, scripts can be ordered, to determine in which order they're injected into the page. The default value for priority is zero. Values higher than zero, will be executed before scripts with lower value and vice versa. To run a script after all default set scripts, you can define a negative integer.

Example Usage

Below are examples demonstrating how to configure scripts for different pages.

Example 1: Script applied on all pages

{
	"title": "MyStylesheet",
	"description": "I'm a stylesheet!",
	"type": "stylesheet",
	"url": "https://my-stylesheet-url.css",
	"pageType": null,
	"slug": null,
	"enabled": true,
    "priority": 10,
	"options": {
		"crossorigin": "anonymous",
		"blocking": false
	}
}

Example 2: Script applied on all pages of type 'default'.

{
	"title": "MyScript",
	"description": "I'm a script!",
	"type": "jsScript",
	"url": "https://my-script-url.js",
	"pageType": "default",
	"slug": null,
	"enabled": true,
    "priority": -1,
	"options": {
		"defer": true
	}
}

Example 3: Script applied on the default page with slug 'my-specific-page'.

{
	"title": "MyScript",
	"description": "I'm a script!",
	"type": "jsScript",
	"url": "https://my-script-url.js",
	"pageType": "default",
	"slug": "my-specific-page",
	"enabled": true,
    "priority": 99,
	"options": {
		"defer": true
	}
}

Example 4: Script applied on the product page for a specific product.

Slugs on for pages of type product, equal the id of the product.

{
	"title": "MyStylesheet",
	"description": "I'm a stylesheet!",
	"type": "stylesheet",
	"url": "https://my-stylesheet-url.css",
	"pageType": "product",
	"slug": "1234567890",
	"enabled": true,
    "priority": 1,
	"options": {
		"crossorigin": "anonymous",
		"blocking": false
	}
}

Warnings

When using stylesheets inside a next/head tag, next.js will give the following warning while in development mode:

⚠️
Do not add stylesheets using next/head. Use Document instead.

This error refers to the following issue that is stated in the documentation (opens in a new tab) of next.js and should be kept in mind, when working on developing Shophub.

We don't recommend this pattern because it will potentially break when used with Suspense and/or streaming. In these contexts, next/head tags aren't:

  • guaranteed to be included in the initial SSR response, so loading could be delayed until client-side rendering, regressing performance.
  • loaded in any particular order. The order that the app's Suspense boundaries resolve will determine the loading order of your stylesheets.