Skip to main content

React single page applications

note

These instructions cover instructions for SPAs built using React. For general SPA integration documentation, visit this page.

Integrating Rokt into a single page application (SPA) requires more consideration compared to standard multi-page applications. SPAs preserve the state between page transitions, operating more like native apps than traditional websites.

In the case of a React SPA, Rokt should be launched once as a singleton. When a placement is ready to be rendered, the application can interact with the singleton.

You can use React Context to hold a reference to the singleton. With React Hooks, you can obtain and interact with that singleton reference.

To see an example, visit our GitHub repository.

React Context Wrapper#

Here is an example of a context provider for Rokt.

import React, { createContext, useContext, useMemo } from "react";
export const RoktContext = createContext();export const RoktContextConsumer = RoktContext.Consumer;
export function useRokt() {  return useContext(RoktContext);}
export function RoktContextProvider({  children,  tagId,  sandbox = false,  windowRef = window,}) {  const roktWrapper = useMemo(() => {    // A Promise that will resolve after Rokt has initialized    const roktLoaded = new Promise((resolve) => {      // This is an exploded form of the initialization tag      // found on the Rokt documentation website      windowRef._ROKT_ = "rokt";      windowRef.rokt = {        id: tagId,        lc: [          // Once loaded, don't select Rokt placements immediately          (rokt) =>            rokt.init({              skipInitialSelection: true,              sandbox,            }),          // Resolve the Rokt instance          (rokt) => resolve(rokt),        ],        it: new Date(),      };      // Create and load a script tag that contains the Rokt bootstrapper      const target = windowRef.document.head || windowRef.document.body;      const script = windowRef.document.createElement("script");      script.type = "text/javascript";      script.src = "https://apps.rokt.com/wsdk/integrations/snippet.js";      script.crossOrigin = "anonymous";      script.async = true;      target.appendChild(script);    });
    // Expose some public methods from the context for components to consume    function setAttributes(attributes) {      roktLoaded.then((rokt) => {        rokt.setAttributes(attributes);      });    }
    function triggerPageChange(pageIdentifier) {      roktLoaded.then((rokt) => {        rokt.triggerPageChange({          pageIdentifier,        });      });    }
    function closeAll() {      roktLoaded.then((rokt) => {        rokt.closeAll();      });    }
    return {      setAttributes,      triggerPageChange,      closeAll,    };  }, [tagId, sandbox]);
  // Return the context provider  return (    <RoktContext.Provider value={roktWrapper}>{children}</RoktContext.Provider>  );}

Consuming Context#

Application Root#

Wrap your App component in this context provider:

ReactDOM.render(  <RoktContextProvider tagId="YOUR_ROKT_TAG_ID" sandbox={true}>    <App />  </RoktContextProvider>);

You have to set sandbox to false when deploying to production.

On the Route#

On the page that shows the Rokt placement, use the Rokt singleton and tell it to trigger a Rokt selection:

import React, { useEffect, useRef } from "react";import { useRokt } from "../context/rokt";import { useUserDetails } from "../context/user-details";
// Imagine this is the component for the confirmation page routeexport function ConfirmationPage() {  // Obtain the user details from an internal location  const userDetails = useUserDetails();  // Obtain the Rokt singleton  const rokt = useRokt();
  useEffect(() => {    // Return if the attributes have not arrived    if (!userDetails.email) {      return;    }    // Set your attributes with the relevant information    rokt.setAttributes({ email: userDetails.email });    // Indicate to Rokt that you'd like to begin the selection    rokt.triggerPageChange("checkout.page");
    // When the page closes, remove all the Rokt placements    return () => {      rokt.closeAll();    };  }, [rokt]);
  return (    <div>      <h1>Confirmation Page</h1>      <div id="rokt-placeholder" />    </div>  );}
Was this article helpful?