# Add Frak to a custom website

# Add Frak to a custom website

For a custom-built site, adding Frak is a matter of loading one script, setting one config object, and dropping in the components you want. Pick the setup that matches your stack below.

**Before you start:** Register your site and add your domain in the [business dashboard](https://business.frak.id/) first. Your merchant ID is then resolved automatically from your domain, so the config below stays short. See [Register your site](/guides/dashboard/register/).

**Rewards need a backend confirmation:** Tracking on the page tells Frak an order might be coming. Rewards only go out once your server confirms the sale with a signed webhook. See [Validate purchases from your backend](/guides/platforms/custom/backend/).

## The components

All three components are framework-agnostic [web components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components), so they work the same whether you write plain HTML, use a bundler, or build with React.

| Component | Where it goes | What it does |
| --- | --- | --- |
| `<frak-button-share>` | Product page, homepage | Lets customers share your store and earn rewards |
| `<frak-banner>` | Top of the page | Welcomes referred visitors |
| `<frak-post-purchase>` | Order confirmation page | Prompts a share right after checkout, and tracks the order |

**Attribute names use dashes:** In HTML and JSX, multi-word attributes must be written with dashes, not camelCase: use `customer-id`, not `customerId`. Browsers lowercase attribute names, so a camelCase attribute is silently ignored.

## Add Frak to your site

### Load and configure Frak

Add this to the `<head>` of your pages. The config object is read by Frak when it loads, so set it **before** the script tag.

```html title="index.html"
<head>
  <!-- 1. Configure Frak (domain defaults to the current host) -->
  <script>
    window.FrakSetup = {
      config: {
        metadata: {
          name: "Your Store",
          currency: "eur",
        },
      },
    };
  </script>

  <!-- 2. Avoid a flash of unstyled elements while the script loads -->
  <style>
    frak-button-share:not(:defined),
    frak-banner:not(:defined),
    frak-post-purchase:not(:defined) { display: none !important; }
  </style>

  <!-- 3. Load the components (auto-registers them and boots the SDK) -->
  <script
    type="module"
    src="https://cdn.jsdelivr.net/npm/@frak-labs/components@latest"
    defer="defer"
  ></script>
</head>
```

### Add the components

Place the banner near the top of your `<body>`, and the share button wherever you want customers to share:

```html
<body>
  <!-- Welcomes referred visitors -->
  <frak-banner></frak-banner>

  <!-- Inherits your theme's .button styles via classname -->
  <frak-button-share classname="button"></frak-button-share>
</body>
```

### Track the purchase

On your order confirmation page, add the post-purchase card with your order details. When `customer-id`, `order-id`, and `token` are all present, the card also registers the order with Frak automatically:

```html
<frak-post-purchase
  customer-id="cust_123"
  order-id="order_456"
  token="a-unique-order-token"
></frak-post-purchase>
```

If you do not want to show the card, register the order directly instead. The action becomes available once Frak is ready:

```html
<script>
  window.addEventListener("frak:client", () => {
    window.FrakSetup.core.trackPurchaseStatus({
      customerId: "cust_123",
      orderId: "order_456",
      token: "a-unique-order-token",
    });
  });
</script>
```

### Install

```bash
npm install @frak-labs/components @frak-labs/core-sdk
```

### Configure Frak

Set the config in its own module so it runs first:

```ts title="frak-setup.ts"
import type { FrakWalletSdkConfig } from "@frak-labs/core-sdk";

declare global {
  interface Window {
    FrakSetup: { config?: FrakWalletSdkConfig };
  }
}

window.FrakSetup = {
  config: {
    metadata: {
      name: "Your Store",
      currency: "eur",
    },
  },
};
```

### Register the components

Import your config module first, then await trackPurchaseStatus({
  customerId: "cust_123",
  orderId: "order_456",
  token: "a-unique-order-token",
});
```

The visual components are the same web components, used inside JSX. Install them and (optionally) `@frak-labs/core-sdk` for direct action calls:

```bash
npm install @frak-labs/components @frak-labs/core-sdk
```

### Configure and register

Set the config in its own module, then import it (and the components) before you render your app:

```ts title="frak-setup.ts"
declare global {
  interface Window {
    FrakSetup: { config?: FrakWalletSdkConfig };
  }
}

window.FrakSetup = {
  config: {
    metadata: {
      name: "Your Store",
      currency: "eur",
    },
  },
};
```

```tsx title="main.tsx"
createRoot(document.getElementById("root")!).render(<App />);
```

### Use the components in JSX

```tsx title="App.tsx"
export function App() {
  return (
    <>
      <frak-banner />
      <frak-button-share classname="button" />

      {/* On your order confirmation route */}
      <frak-post-purchase
        customer-id="cust_123"
        order-id="order_456"
        token="a-unique-order-token"
      />
    </>
  );
}
```

The post-purchase card tracks the order automatically. To track without the card, call `trackPurchaseStatus` from `@frak-labs/core-sdk/actions` after the order is placed.

**TypeScript:** TypeScript may not recognize the `<frak-*>` tags in JSX. Add a small declaration so it does:

```ts title="frak.d.ts"
declare global {
  namespace JSX {
    interface IntrinsicElements {
      "frak-banner": HTMLAttributes<HTMLElement>;
      "frak-button-share": HTMLAttributes<HTMLElement> & { classname?: string; text?: string };
      "frak-post-purchase": HTMLAttributes<HTMLElement> & {
        "customer-id"?: string;
        "order-id"?: string;
        token?: string;
      };
    }
  }
}
```

On React 19, declare the same `namespace JSX` inside `declare module "react"` instead of `declare global`.

**Need programmatic control?:** For custom flows (wallet status, referral hooks, opening the modal yourself), `@frak-labs/react-sdk` exposes React hooks and providers. See the [React integration guide](/developers/integration/react/).

**Every option:** The full attribute list for each component lives in the developer reference: [share button](/developers/components/share-button/), [banner](/developers/components/banner/), [post-purchase](/developers/components/post-purchase/), and the [`FrakSetup` config](/developers/components/frak-setup/).

## Next steps

[Backend validation](/guides/platforms/custom/backend/)
  [Mobile apps](/guides/platforms/custom/mobile/)
  [Components reference](/developers/components/)
  [Vanilla JS / CDN guide](/developers/integration/cdn/)