Core Functionalities
Analytics API

Analytics Features

Now, you can easily capture and visualize key storefront events and metrics, This allows you to gain deep insights into your customer behavior and engagement, empowering data-driven decisions to optimize your online storefront.

The storefront analytics feature provides:

  • Customizable, responsive charts and graphs to display critical metrics like traffic, sales, conversions, and more
  • Automated tracking and reporting of customer actions such as page views, add-to-carts, checkouts, and other events
  • Seamless integration of the analytics data directly into your application interface
  • Flexible configuration to match the branding and styling of your storefront
  • With this new functionality, you can quickly identify trends, troubleshoot issues, and uncover opportunities to enhance the customer experience. The storefront analytics feature is a valuable addition to our codebase, putting the power of data-driven insights at your fingertips.

Overview

ShipReady uses Shopify/polaris-viz (opens in a new tab), which is native to Shopify Admin.

  • Charts provider wrapper & theme
  • Chart dependencies on build
  • Rendering charts
  • Handling/storing storefront events
  • Example on displaying events

Charts provider wrapper & theme

In other for charts to get properly displayed:

  1. They have to be inside PolarisVizProvider. Not only it provides the elements and animations but also theme configuration.
  2. We have already Created a wrapper called ChartProvider from PolarisVizProvider that can be configured once and re-used and it's added at top level route.
    export default function App() {
        const { apiKey } = useLoaderData();
     
        return (
            <AppProvider isEmbeddedApp apiKey={apiKey}>
            <Nav />
            <ChartProvider>
                <Outlet />
            </ChartProvider>
            </AppProvider>
        );
    }
  3. Theme configuration are general settings like chart's background color and convas overall padding etc..., and should be configured in ChartProvider the Wrapper:
    export default function ChartProvider({ children }) {
        const themes = {
            your_theme_name: {
                chartContainer: {
                    borderRadius: "0",
                    padding: "0",
                    minHeight: 300,
                },
                grid: {
                    horizontalOverflow: false,
                    horizontalMargin: 0,
                    verticalOverflow: false,
                },
            },
        };
        return <PolarisVizProvider themes={themes}>{children}</PolarisVizProvider>;
    }

Note: you can add a new theme or update the existing one, more details can be found here (opens in a new tab)

  1. Adding chart's css styles

    import polarisStyles from "@shopify/polaris/build/esm/styles.css?url";
    .
    .
    export const links = () => [ { rel: "stylesheet", href: polarisStyles } ];

Chart dependencies on build

Due to SSR (server-side-rendering) Feature of RemixJS framework, chart dependencies aren't getting bundled on build since they are not recognized as ViteJs linked dependencies (opens in a new tab). So to include them on build time, add them to vite.config.js file as below.

export default defineConfig({
  ssr: {
    noExternal: [ // List of dependencies that has to be included on build time.
      "/remix-utils/",
      "@shopify/polaris-viz",
      "@juggle/resize-observer",
      "@react-spring/animated",
      "@react-spring/core",
      "@react-spring/shared",
      "@react-spring/types",
      "@react-spring/web",
      "@shopify/polaris-viz",
      "@shopify/polaris-viz-core",
      "d3-array",
      "d3-color",
      "d3-format",
      "d3-interpolate",
      "d3-path",
      "d3-scale",
      "d3-shape",
      "d3-time",
      "d3-time-format",
      "internmap",
      "use-debounce",
    ],
  },
  ...
})
 

Rendering charts

As mentioned above, charts can't be SSR so for that we have use useEffect() to render them once they are on client-side, for example:

import { BarChart } from "@shopify/polaris-viz";
export const ExampleChart = ({ children, theme }) => {
  const [chart, setChart] = useState(null);
  const chartMarkup = (
    <BarChart
        showLegend={true}
        data={data}
        isAnimated={true}
        type="stacked"
        xAxisOptions={{
        labelFormatter: (value) => {
            return value?.optionName;
        },
        }}
    />
  );
 
  useEffect(() => setChart(chartMarkup), []); // Here we set chart markup
  return chart;
};

Handling/storing storefront events

Before handling events we will have to fire them, and to do so we simply:

  1. Enable App Embed
    • Click on Online Store > Themes
    • Click on the current theme Customize
    • App embeds > ShipReady Assets
    • Enable the app embed and click Save
  2. In your theme use this script when onclick, onblur and etc ...
shipready.push('add-to-cart', {productId: 'gid://shopify/Product/1234567890'}) 

Now that we can fire events, to handle them:

  1. Update APP_NAME in extensions/theme-extension/js/app.js from handle key in shopify.app.toml.

  2. Make sure the App Proxy is setup or setup correctly. details can be found here (opens in a new tab)

  3. Now, all events are redirected to endpoint /api/events in app > routes > api.events.jsx file, where you can handle them as below:

    export const action = async ({ request }) => {
        try {
            const {
            admin,
            session: { shop },
            } = await authenticateProxy(request);
            const { event, details, timestamp } = await request.json(); // event's name and details
     
            // You can handle you business logic here
            await EventModel.create({ shop, name: event, data: details }); // inserts new event to Event table
     
            return json({ message: "The event has been successfully tracked!" });
        } catch (e) {
            console.error(e);
            return json({ error: e });
        }
    };

Example on displaying events

To display events data on graphs, we need to pull data from database events table, and manipulate them to create the specified structure (opens in a new tab) based on the chart type. and feed it the chart to be displayed.

Example

  • From the app > components > chart > main, suppose we select the chart type lineChart.jsx
  • We create a component in chart folder call it totalSales.jsx
  • Here is a example data with line-chart data structrue, normally it should be generated from the event table data.
    export const totalSales = [
    {
        name: "July 1 - July 7, 2024",
        data: [
            {
                value: 600,
                key: "July 1, 2024",
            },
            {
                value: 530,
                key: "July 2, 2024",
            },
            {
                value: 690,
                key: "July 3, 2024",
            },
            {
                value: 590,
                key: "July 4, 2024",
            },
            {
                value: 710,
                key: "July 5, 2024",
            },
            {
                value: 630,
                key: "July 6, 2024",
            },
            {
                value: 900,
                key: "July 7, 2024",
            }, 
        ],
    },
    {
        name: "Previous month",
        data: [
            {
                value: 450,
                key: "June 1, 2024",
            },
            {
                value: 340,
                key: "June 2, 2024",
            },
            {
                value: 480,
                key: "June 3, 2024",
            },
            {
                value: 390,
                key: "June 4, 2024",
            },
            {
                value: 509,
                key: "June 5, 2024",
            },
            {
                value: 450,
                key: "June 6, 2024",
            },
            {
                value: 603,
                key: "June 7, 2024",
            },
        ],
        isComparison: true,
    },
];
  • Add the data to chart component, use useLoaderData to get data from the server.
import { useLoaderData } from "@remix-run/react";
import { LineChart } from "./main/lineChart";
 
export const TotalSales = () => {
    const { data } = useLoaderData();
    const title = "Total sale"
    const total = "$54,042.24"
    const fluctuation  = 10.7
    return (
        // simply replace the data provided below 😉
        <LineChart
        title={title}
        subTitle={total}
        fluctuation={fluctuation}
        data={data}
        />
    );
};