Skip to main content
The Sleekplan widget is a plain script snippet, so it works in any React app. The only thing to get right is when it loads: run it once, after your app has mounted, so the script attaches to a page that already exists.
First grab your snippet from Settings → Widget and copy your SLEEK_PRODUCT_ID. See Install the Sleekplan widget for the basics.

Function components (hooks)

Add the widget from a useEffect hook in your top-level component (for example App). The empty dependency array [] makes it run once, right after the first render.
import { useEffect } from "react";

function App() {
  useEffect(() => {
    window.$sleek = [];
    window.SLEEK_PRODUCT_ID = YOUR_PRODUCT_ID;

    const s = document.createElement("script");
    s.src = "https://client.sleekplan.com/sdk/e.js";
    s.async = true;
    document.getElementsByTagName("head")[0].appendChild(s);
  }, []);

  return (
    // your app
  );
}

export default App;
Replace YOUR_PRODUCT_ID with the numeric ID from your snippet (leave it unquoted, it is a number).
If your app hot-reloads during development, you may briefly see the launcher appear twice. That is a dev-only side effect of the module reloading, it does not happen in a production build.

Class components

If you still use class components, put the same code in componentDidMount() so it runs after the component is on the page:
class App extends React.Component {
  componentDidMount() {
    window.$sleek = [];
    window.SLEEK_PRODUCT_ID = YOUR_PRODUCT_ID;
    (function () {
      const d = document;
      const s = d.createElement("script");
      s.src = "https://client.sleekplan.com/sdk/e.js";
      s.async = 1;
      d.getElementsByTagName("head")[0].appendChild(s);
    })();
  }

  render() {
    return (
      // your app
    );
  }
}

export default App;

Next.js

In Next.js, use the built-in Script component in your root layout so the snippet loads once across route changes. Give it the afterInteractive strategy and set your product ID before the SDK loads.
import Script from "next/script";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script id="sleek-config" strategy="beforeInteractive">
          {`window.$sleek=[];window.SLEEK_PRODUCT_ID=YOUR_PRODUCT_ID;`}
        </Script>
        <Script
          src="https://client.sleekplan.com/sdk/e.js"
          strategy="afterInteractive"
        />
      </body>
    </html>
  );
}
Because the widget is a client-side script, it only runs in the browser, so there is nothing to render on the server.

Identify your users

Once the widget loads you can attach your signed-in user with the SDK, for example after login:
$sleek.setUser({
  mail: user.email,
  id: user.id,
  name: user.name,
});
For confirmed accounts or private boards, use Single Sign-On instead. The full API is in the Developer Docs.

Next steps

Back to install overview

The snippet, user identification, and other platforms.

Content Security Policy

Allowlist the Sleekplan domains if your app enforces a CSP.