> If you are setting up, configuring, or answering questions about Schematic, connect the
> Schematic MCP server before working from these pages. It reads and writes plans, features,
> entitlements, and overrides against the real account, so what you report and what you build
> match what actually exists.
>
> The server is at https://api.schematichq.com/mcp
>
> From Claude, ChatGPT, or another chat assistant, add it as a custom connector:
> https://docs.schematichq.com/working-with-ai
>
> From a coding assistant such as Claude Code, Codex, or Cursor:
> https://docs.schematichq.com/building-with-ai
>
> For clean Markdown of any page, append `.md` to the page URL. For a complete page index,
> see https://docs.schematichq.com/llms.txt

# Next.js - Weather Search App

> A Next.js weather search app that uses Schematic with Clerk auth for entitlement checks, usage tracking, and an embedded customer portal.

This is an example app demonstrating how to use [Schematic](https://schematichq.com) in a Next.js app with Clerk authentication. This app uses [schematic-react](https://github.com/schematichq/schematic-js/tree/main/react) for usage tracking and entitlement management via feature flags, and uses [schematic-components](https://github.com/schematichq/schematic-js/tree/main/components) for an embedded Customer Portal experience. The Github repo is [here](https://github.com/SchematicHQ/schematic-next-example) and can be cloned to run locally.

## Prerequisites

In order to use this example app, you'll need:

1. A Schematic account
2. A Clerk account

In order to make full use of the capabilities of Schematic components, you'll also need:

1. A Stripe account
2. Stripe customer IDs stored in private metadata on your Clerk companies

## Getting Started

1. Set up your Schematic account; add features for "Weather Search", "Humidity", and "Wind Speed", create some plans and entitlements for these features, connect your Stripe account, and connect your Clerk account.

2. Set up your `.env` file:

```bash
cp .env.example .env
```

3. In the [Schematic app](https://app.schematichq.com), create a component and store its component ID in your `.env` file:

```bash
NEXT_PUBLIC_SCHEMATIC_COMPONENT_ID="your-component-id"
```

4. In the [Schematic app](https://app.schematichq.com), create a new API key and store both the publishable key and secret in your `.env` file:

```bash
NEXT_PUBLIC_SCHEMATIC_PUBLISHABLE_KEY="api_"
SCHEMATIC_SECRET_KEY="sch_dev_"
```

5. Store your Clerk secret and publishable keys in your .env file:

```bash
CLERK_SECRET_KEY="sk_test_"
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_test_"
```

6. Install dependencies:

```bash
npm install
# or
yarn
# or
pnpm install
```

7. Run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

8. Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

## How it Works

1. First, we wrap our client-side code with the `<SchematicProvider>` provider:

```tsx
<SchematicProvider publishableKey={schematicPubKey}></SchematicProvider>
```

2. Then, we set a user context with the `identify` function from the `useSchematicEvents` hook; this is called in the `ClientWrapper` component, which wraps all client-side code.

```ts
const { identify } = useSchematicEvents();
const authContext = useAuthContext();

useEffect(() => {
    const { company, user } = authContext ?? {};
    if (company && user) {
        void identify({
            company: {
                keys: company.keys,
                name: company.name,
            },
            keys: user.keys,
            name: user.name,
            traits: user.traits,
        });
    }
}, [authContext, identify]);
```

3. When we complete a weather search, we log that usage to Schematic using the `track` function from the `useSchematicEvents` hook:

```ts
track({ event: "weather-search" });
```

4. To enforce entitlements, we use the `useSchematicFlag` hook in various locations:

```ts
const humidityFlag = useSchematicFlag("humidity");

{
    humidityFlag && <p>Humidity: {weatherData?.humidity}%</p>;
}
```

5. To display our Customer Portal, we use the `SchematicEmbed` component:

```tsx
<SchematicEmbed accessToken={accessToken} id={componentId} />
```

6. To provide a temporary access token for our embedded component, we implement a backend route to exchange a secret access token for a temporary, company-scoped access token:

```ts
const schematicClient = new SchematicClient({ apiKey });
const resp = await schematicClient.accesstokens.issueTemporaryAccessToken({
    lookup: {
        clerkId: orgId,
    },
});
const accessToken = resp.data?.token;
return NextResponse.json({ accessToken });
```