Run app code on a page

Run app or snippet code on every page of a kind with the SDK event page::view, so it works after client-side navigation.

Use this when a store app or a snippet adds something to one kind of page, such as a widget on every product page.

Goal: the code runs on each product page the customer opens, in a React theme and a classic theme alike.

On a classic theme every page is a full load, so a snippet can check the page once:

// Runs once. In the React theme that is only the page the customer landed on.
if (Salla.url.is_page('product.single')) mountWidget();

In the React theme, links navigate in the browser without reloading. That snippet runs once, on the first page, and the engine renders later pages fresh. A widget it added is replaced, and a product page the customer opens later never gets one.

Listen for page::view

The Twilight SDK dispatches page::view with the page the customer is looking at: once when it has started, then after every navigation in the browser (it follows the engine's route::changed). A classic theme loads each page, so there it fires once per page too. The same code works in both:

Salla.event.on('page::view', (page) => {
  if (page.slug === 'product.single') mountWidget(page.id);
  else removeWidget();
});

The handler gets the page: slug, id, title, url, and breadcrumbs when the page has them. A 404 sends an empty object, so check slug.

  • It is sticky. A handler added after the first page::view, such as a snippet that loads late, is called straight away with the page on screen, then on every later one.
  • Leaving is yours to handle. There is no separate event for it: the next page::view is the signal, as removeWidget() above shows.
  • Opening another product is a new page view. Changing filters or sorting on the same page is not.

Snippets that still check Salla.url.is_page('product.single') once, outside a page::view handler, keep working: the engine loads the page fully when the customer navigates to or from a page they name, as classic themes do. Those navigations lose the speed of in-browser navigation, so move the snippet to page::view.

Only a positive check that names the page counts. A negated check (!Salla.url.is_page('cart')), a read of page.slug or config.get('page'), or a slug held in a variable runs once, on the page the customer landed on, because reloading for it would reload every page.

Where to go next

On this page