Upgrading from V1 to V2

This guide outlines some of the biggest changes you need to make to upgrade from V1 to V2. Scroll down to the bottom for instructions on how to use V1 and V2 at the same time.

Provider theme

In V2, we have a fully-fledged theming system that allows you to customize every token in our design system. If you used V1’s theme colors, you can convert them to V2 like so:

// V1
<FrigadeProvider
  config={{
    defaultAppearance: {
      theme: {
        colorText: '#3d3d3d',
        colorTextSecondary: '#494949',
        colorTextOnPrimaryBackground: '#fff',
        colorPrimary: '#2956B5',
        colorBorder: '#E2E2E2',
      }
    }
  }}
>

// V2
<Frigade.Provider
  theme={{
    colors: {
      neutral: {
        // Replaces colorBorder
        border: '#E2E2E2',

        // Replaces colorText
        foreground: '#3d3d3d'
      },
      primary: {
        // Replaces colorTextOnPrimaryBackground
        foreground: '#fff',

        // Replaces colorPrimary
        surface: '#2956B5'
      }
    }
  }}
>

Note that colorTextSecondary was deprecated and doesn’t have a V2 equivalent.

Global style overrides

We no longer wrap descendents of the Frigade Provider in a container element, as we found that for most users adding an extra wrapper to the DOM at (or near) the top was more disruptive than helpful.

As a result, we no longer support the config.defaultAppearance.styleOverrides property that existed on FrigadeProvider in V1.

We now recommend that you author global styles using your existing CSS workflow.

Component style overrides

We use Emotion’s CSS prop in V2, so you can write any CSS that Emotion supports directly on any component:

// V1
<FrigadeAnnouncement
  appearance={{
    styleOverrides: {
      'button': {
        backgroundColor: 'fuchsia'
      }
    }
  }}
/>

// V2
<Frigade.Announcement
  css={{
    '.fr-button-primary': {
      backgroundColor: 'fuchsia',

      '&:hover': {
        backgroundColor: 'lilac'
      }
    },
  }}
/>

Important difference between V1 styleOverrides and V2 css props:

The V2 css prop accepts a style object, which means that if you’re using V1’s styleOverrides prop to pass Tailwind classNames through to sub-components, you’ll need to update your code to pass Tailwind’s arbitrary variants, e.g.:

// V1
<FrigadeAnnouncement
  appearance={{
    styleOverrides: {
      'button': 'w-full'
    }
  }}
/>

// V2
<Frigade.Announcement
  className="[&_button]:w-full"
/>

The navigate prop is now a top-level prop on Provider, it is no longer nested inside config:

// V1
<FrigadeProvider
  config={{
    navigate: (url, target): void => {
      if (target === "_blank") {
        window.open(url, "_blank");
      } else {
        router.push(url);
      }
    },
  }}
>

// V2
<Frigade.Provider
  navigate={(url, target) => {
    if (target === "_blank") {
      window.open(url, "_blank");
    } else {
      router.push(url);
    }
  }}
>

Event handlers

The catch-all onButtonClick prop has been replaced with individual handlers for onPrimary, onSecondary, onDismiss, and onComplete.

Full definitions of each handler are available in our component docs

Hooks

Our SDK hooks now expose objects from our JS SDK directly, for example useFlow returns an instance of Flow, which you can operate directly on as you would in the JS SDK.


Running V1 and V2 together

If you already have a V1 implementation and aren’t ready to fully upgrade yet, you can use both V1 and V2 at the same time. This setup allows you to import V1 components from @frigade/react and V2 components from @frigade/reactv2.

Instructions

1

First, install V2 using a package alias:

"dependencies": [
"@frigade/react": "1.x",
"@frigade/reactv2": "npm:@frigade/react@2.x",
]
2

Then add the V2 `Provider` above the V1 `FrigadeProvider`:

import { FrigadeProvider } from "@frigade/react";
import * as Frigade from "@frigade/reactv2";

const FRIGADE_API_KEY = "api_public_abcd1234";

export const App = () => {
  const userId = "...";

  return (
    <Frigade.Provider apiKey={FRIGADE_API_KEY} userId={userId}>
      <FrigadeProvider publicApiKey={FRIGADE_API_KEY} userId={userId}>
        {/* ... */}
      </FrigadeProvider>
    </Frigade.Provider>
  );
};

Common Issue

When using V1 and V2 together, state is not shared between the two providers. Be sure to call frigade.reload() from the useFrigade() hook (V2) and/or refresh() from the useFlows() (V1).