npm package: @makerinc/ssr-component
Description: React component for embedding Maker projects with server-side rendering
Latest version: 1.1.0

# @maker/ssr-component

React component for embedding [Maker](https://ai.maker.co) projects with server-side rendering (SSR).

## Why Server-Side Rendering?

Server-side rendering means your content is fully prepared on the server before it reaches your visitor's browser. Think of it like having a chef prepare your meal in the kitchen rather than asking you to cook it yourself at your table.

**Key Benefits:**

- **Faster Loading**: Users see content immediately instead of waiting for JavaScript to build the page
- **Better SEO**: Search engines can easily read and index your content, improving your website's discoverability
- **Improved Accessibility**: Screen readers and other assistive technologies get complete content right away
- **Reliable Performance**: Your content displays properly even if JavaScript fails to load or is disabled

> **⚠️ Important Note**: SSR may not work properly with pages that contain animated components or complex interactive elements that rely on client-side state. Animations and dynamic behaviors are captured as static snapshots during server-side rendering.

## Features

- Server-side rendering for optimal performance
- SEO-friendly with meta tags and proper HTML structure
- TypeScript support
- Works with Next.js, React Server Components, and any React framework

## Installation

```bash
npm install @maker/ssr-component
```

or

```bash
yarn add @maker/ssr-component
```

or

```bash
pnpm add @maker/ssr-component
```

## Prerequisites

Before using this package, you'll need:

1. **API Key**: A Maker SSR API key (contact Maker team to obtain one)
2. **Project ID**: The unique identifier for your Maker project

Set your API key as an environment variable:

```env
MAKER_SSR_API_KEY=your_api_key_here
```

## API Key Handling

The `MakerComponent` requires an `apiKey` prop to authenticate with the Maker SSR API. Here are the recommended patterns:

### Environment Variable (Recommended)

Store your API key in environment variables and pass it to the component:

```tsx
const apiKey = process.env.MAKER_SSR_API_KEY!;

<MakerComponent apiKey={apiKey} projectId="your_project_id" />;
```

### Validation Pattern

Always validate the API key before rendering:

```tsx
export default async function Page() {
  const apiKey = process.env.MAKER_SSR_API_KEY;

  if (!apiKey) {
    throw new Error("MAKER_SSR_API_KEY is required");
  }

  return <MakerComponent apiKey={apiKey} projectId="your_project_id" />;
}
```

### Graceful Error Handling

For better user experience, handle missing API keys gracefully:

```tsx
export default async function Page() {
  const apiKey = process.env.MAKER_SSR_API_KEY;

  if (!apiKey) {
    return <div>Configuration error: API key not found</div>;
  }

  return <MakerComponent apiKey={apiKey} projectId="your_project_id" />;
}
```

**Security Note:** Never expose your API key in client-side code. Always access it from environment variables on the server side.

## Usage

### Next.js (App Router)

**Basic Usage:**

```tsx
import { MakerComponent } from "@maker/ssr-component";

export default async function Page() {
  const apiKey = process.env.MAKER_SSR_API_KEY!;

  return (
    <div>
      <h1>My Page</h1>
      <MakerComponent
        apiKey={apiKey}
        projectId="your_project_id"
        options={{
          debug: false,
          device: "desktop",
        }}
      />
    </div>
  );
}
```

**With API Key Validation:**

```tsx
import { MakerComponent } from "@maker/ssr-component";

export default async function Page() {
  const apiKey = process.env.MAKER_SSR_API_KEY;

  if (!apiKey) {
    return (
      <div>
        <h1>Configuration Error</h1>
        <p>MAKER_SSR_API_KEY is not configured</p>
      </div>
    );
  }

  return (
    <div>
      <h1>My Page</h1>
      <MakerComponent
        apiKey={apiKey}
        projectId="your_project_id"
        options={{
          debug: false,
          device: "desktop",
        }}
      />
    </div>
  );
}
```

**With Cache Busting:**

Use `cacheBust: true` to bypass the cache and fetch fresh content. This is useful during development or when you need to ensure users see the latest version:

```tsx
import { MakerComponent } from "@maker/ssr-component";

export default async function Page() {
  const apiKey = process.env.MAKER_SSR_API_KEY!;

  return (
    <div>
      <h1>My Page</h1>
      <MakerComponent
        apiKey={apiKey}
        projectId="your_project_id"
        options={{
          device: "desktop",
          cacheBust: true, // Bypass cache and fetch fresh content
        }}
      />
    </div>
  );
}
```

**With Version Specification:**

Use the `version` option to render a specific version of your Maker project:

```tsx
import { MakerComponent } from "@maker/ssr-component";

export default async function Page() {
  const apiKey = process.env.MAKER_SSR_API_KEY!;

  return (
    <div>
      <h1>My Page</h1>
      <MakerComponent
        apiKey={apiKey}
        projectId="your_project_id"
        options={{
          device: "desktop",
          version: "1767692001255", // Render specific version
        }}
      />
    </div>
  );
}
```

### Next.js (Pages Router)

```tsx
import { MakerComponent } from "@maker/ssr-component";

export default function Page({ pageData }) {
  return (
    <div>
      <h1>My Page</h1>
      {/* You'll need to implement the server-side fetch yourself */}
    </div>
  );
}

export async function getServerSideProps() {
  // Fetch data server-side
  const response = await fetch("https://ssr.maker.new/api/ssr/v1/content", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.MAKER_SSR_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      idn: "your_project_id",
    }),
  });

  const pageData = await response.json();
  return { props: { pageData } };
}
```

### Custom React SSR Setup

If you're using a custom React SSR setup, you can import and use the components directly:

```tsx
import { MakerComponent } from "@maker/ssr-component";

// In your server-side rendering function
async function renderPage() {
  const apiKey = process.env.MAKER_SSR_API_KEY;

  if (!apiKey) {
    throw new Error("MAKER_SSR_API_KEY environment variable is not set");
  }

  return (
    <html>
      <body>
        <MakerComponent apiKey={apiKey} projectId="your_project_id" />
      </body>
    </html>
  );
}
```

## API Reference

### MakerComponent

The main component for embedding Maker projects.

#### Props

| Prop        | Type                    | Required | Description                       |
| ----------- | ----------------------- | -------- | --------------------------------- |
| `apiKey`    | `string`                | Yes      | Your Maker SSR API key            |
| `projectId` | `string`                | Yes      | Your Maker project ID             |
| `options`   | `MakerComponentOptions` | No       | Configuration options (see below) |

#### MakerComponentOptions

| Option      | Type                                | Default | Description                                  |
| ----------- | ----------------------------------- | ------- | -------------------------------------------- |
| `debug`     | `boolean`                           | `false` | Enable debug logging                         |
| `device`    | `"mobile" \| "desktop" \| "tablet"` | -       | Specify device type for responsive rendering |
| `cacheBust` | `boolean`                           | `false` | Bypass cache and fetch fresh content         |
| `version`   | `string`                            | -       | Specify version of the project to render     |

### MakerClientScripts

A client-side component that handles script hydration. This is used internally by `MakerComponent` but can be used separately if needed.

#### Props

| Prop      | Type       | Required | Description                |
| --------- | ---------- | -------- | -------------------------- |
| `scripts` | `Script[]` | Yes      | Array of scripts to inject |

### Types

```typescript
export type MakerComponentOptions = {
  debug?: boolean;
  device?: "mobile" | "desktop" | "tablet";
  cacheBust?: boolean;
  version?: string;
};

export type Script = {
  src: string;
  inline: string | null;
  type?: string;
};

export type PageData = {
  meta: Array<{
    charset?: string;
    name?: string;
    property?: string;
    content?: string;
  }>;
  fonts: string[];
  title: string;
  stylesheets: string[];
  inlineStyles: string[];
  scripts: Script[];
  body: string;
};
```

## Environment Variables

| Variable            | Required | Description        |
| ------------------- | -------- | ------------------ |
| `MAKER_SSR_API_KEY` | Yes      | Your Maker API key |

## How It Works

1. **Server-Side**: The component fetches pre-rendered content from the Maker SSR API
2. **Render**: HTML content, styles, and metadata are injected into your page
3. **Client Hydration**: JavaScript loads and executes, making the content interactive
4. **Interactive**: The embedded project becomes fully functional after hydration

## Caching and Performance

The Maker SSR API caches content by default for optimal performance. You have several options to control caching behavior:

### Cache Busting

Use the `cacheBust` option to bypass the cache and fetch fresh content:

```tsx
<MakerComponent
  apiKey={apiKey}
  projectId="your_project_id"
  options={{ cacheBust: true }}
/>
```

**Note:** Set `cacheBust: true` during development or when you need to ensure users see the latest version. For production, rely on caching strategies below for better performance.

### Next.js App Router

Use Next.js revalidation for caching:

```tsx
import { MakerComponent } from "@maker/ssr-component";

// Revalidate every 60 seconds
export const revalidate = 60;

export default async function Page() {
  const apiKey = process.env.MAKER_SSR_API_KEY!;

  return <MakerComponent apiKey={apiKey} projectId="your_project_id" />;
}
```

### Custom Caching

Implement your own caching strategy to reduce API calls:

```tsx
import { cache } from "react";

const getMakerContent = cache(async (projectId: string) => {
  // Your caching logic here
  // Could use Redis, memory cache, etc.
});
```

## Troubleshooting

### Error: MAKER_SSR_API_KEY is not set

Make sure you've set the `MAKER_SSR_API_KEY` environment variable:

```env
MAKER_SSR_API_KEY=your_api_key_here
```

### Styles Not Loading

- Verify your Content Security Policy allows external resources from Maker CDN
- Check browser console for CORS errors
- Ensure stylesheet URLs are accessible

### Scripts Not Executing

- Check browser console for JavaScript errors
- Verify the `DOMContentLoaded` event is being fired
- Check for Content Security Policy restrictions

## Requirements

- React >= 18.0.0
- react-dom >= 18.0.0

## License

MIT

## Support

For issues, questions, or feature requests, contact the Maker team at [ai.maker.co](https://ai.maker.co).