The Frill Script

Framework integration (React, Vue, Angular, Next.js)

For React, Next.js, and other JavaScript frameworks, install the type-safe @frillco/script package. It embeds Frill Widgets, Surveys, and Boosted Announcements. Vue and Angular apps can use the same package API, or load the script tag like any other third-party script.

Install the package

Add the SDK to your project:

npm install @frillco/script

Your container key is in Settings > Frill Script on the React / Next.js tab. Full documentation is on developers.frill.co.

React

Mount FrillScript once—for example in your root layout—so the container loads for the whole app.

import { FrillScript } from '@frillco/script/react';

// Render once, e.g. in your root layout
<FrillScript
  container={{
    key: 'YOUR_CONTAINER_KEY',
    // Identify your users (optional)
    // user: { email: '[email protected]', name: 'Mitch' }
  }}
/>

You can also copy a prefilled snippet from Settings > Frill Script on the React / Next.js tab.

Next.js

In the App Router, render FrillScript in the root layout and pass Next.js Script so the container loads before hydration.

import Script from 'next/script';
import { FrillScript } from '@frillco/script/react';

// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <FrillScript
          as={Script}
          strategy="beforeInteractive"
          container={{
            key: 'YOUR_CONTAINER_KEY',
            // Identify your users (optional)
            // user: { email: '[email protected]', name: 'Mitch' }
          }}
        />
      </body>
    </html>
  );
}

If you use the Pages Router, mount the same component from your shared root document so it loads on every page.

Use the SDK without React components

In any JavaScript or TypeScript app, call frill from the package. The first call loads the script.

import { frill } from '@frillco/script';

// Load your container (optionally identifying the current user)
await frill('container', {
  key: 'YOUR_CONTAINER_KEY',
  user: { name: 'Mikey Hill', email: '[email protected]' },
});

// Open a specific Widget on demand
const widget = await frill('widget', { key: 'YOUR_WIDGET_KEY' });
widget.open();

To start loading immediately, call loadFrill():

import { loadFrill } from '@frillco/script';

loadFrill();
// loadFrill({ domain: 'frill.eu' });

React hooks and inline Widgets

The React entry point also exports hooks and an inline embed component.

import { useWidget, FrillWidgetEmbed } from '@frillco/script/react';

function FeedbackButton() {
  const widget = useWidget({ key: 'YOUR_WIDGET_KEY' });

  return (
    <button type="button" onClick={() => widget?.open()}>
      Feedback
    </button>
  );
}

function InlineWidget() {
  return (
    <FrillWidgetEmbed
      widgetKey="YOUR_WIDGET_KEY"
      style={{ width: 340, height: 460 }}
    />
  );
}

Available React helpers:

  • useFrill — returns frill and loads the script on mount

  • useContainer — returns the container instance or null

  • useWidget — returns a Widget instance or null

  • useSurvey — returns a Survey instance or null

  • FrillWidgetEmbed — renders an inline Widget

For open, close, navigation, and event APIs after a Widget loads, see Controlling widgets programmatically.

Vue and Angular

There is no separate Vue or Angular package export. Use frill and loadFrill from @frillco/script, or paste the script tag from Installing the Frill Script into your root template the same way you load other third-party scripts. Frill still creates and removes Widgets and Surveys based on your dashboard settings.

Conditional loading

Disable automatic loading of Widgets and Surveys when you initialize the container with autoLoad.

import { frill } from '@frillco/script';

await frill('container', {
  key: 'YOUR_CONTAINER_KEY',
  // Pass false to disable automatic Widget and Survey loading
  autoLoad: false, // Also accepts: 'widgets' or 'surveys'
});

The autoLoad option accepts:

  • true (default) — auto-load Widgets and Surveys based on targeting

  • false — load nothing automatically; you load Widgets and Surveys yourself

  • "widgets" — auto-load only Widgets

  • "surveys" — auto-load only Surveys

When auto-loading is off, load a Widget manually:

const widget = await frill('widget', {
  key: 'YOUR_WIDGET_KEY',
  callbacks: {
    onReady(widget) {
      console.log(widget);
    },
  },
});

You can also show a Widget or Survey with URL and audience targeting in the Frill settings. A launcher set to None leaves open and close control to your own code.

Content Security Policy nonce

If your site requires a script nonce, pass it to FrillScript or loadFrill:

<FrillScript nonce={nonce} container={{ key: 'YOUR_CONTAINER_KEY' }} />
loadFrill({ nonce });
Was this helpful?