npm package: @launchlysites/nextjs-sdk
Description: Next.js SDK for LaunchlySites CMS - Build fast, SEO-friendly websites with headless content management
Author: LaunchlySites
Latest version: 1.0.0

# LaunchlySites Next.js SDK

Official Next.js SDK for LaunchlySites CMS - Build fast, SEO-friendly websites with headless content management.

## Installation

```bash
npm install @launchlysites/nextjs-sdk
# or
yarn add @launchlysites/nextjs-sdk
```

## Quick Start

### 1. Setup Provider

Wrap your app with the LaunchlySites provider:

```tsx
// app/layout.tsx or pages/_app.tsx
import { LaunchlySitesProvider } from '@launchlysites/nextjs-sdk';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <LaunchlySitesProvider
          config={{
            apiUrl: process.env.NEXT_PUBLIC_LAUNCHLY_API_URL!,
            projectId: process.env.NEXT_PUBLIC_LAUNCHLY_PROJECT_ID!,
            apiKey: process.env.LAUNCHLY_API_KEY, // Optional for public content
          }}
        >
          {children}
        </LaunchlySitesProvider>
      </body>
    </html>
  );
}
```

### 2. Environment Variables

Create a `.env.local` file:

```env
NEXT_PUBLIC_LAUNCHLY_API_URL=https://your-cms-domain.com
NEXT_PUBLIC_LAUNCHLY_PROJECT_ID=your-project-id
LAUNCHLY_API_KEY=your-api-key
```

### 3. Fetch Content

```tsx
// app/blog/page.tsx
'use client';

import { useContent, useContentType } from '@launchlysites/nextjs-sdk';

export default function BlogPage() {
  const { contentType } = useContentType('blog-post-content-type-id');
  const { content, loading, error } = useContent('blog-post-content-type-id', {
    status: 'published',
    limit: 10,
  });

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      <h1>Blog Posts</h1>
      {content.map((post) => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.data.excerpt}</p>
          <div dangerouslySetInnerHTML={{ __html: post.data.content }} />
        </article>
      ))}
    </div>
  );
}
```

### 4. Dynamic Pages

```tsx
// app/blog/[slug]/page.tsx
'use client';

import { useContentBySlug } from '@launchlysites/nextjs-sdk';
import { notFound } from 'next/navigation';

interface Props {
  params: Promise<{ slug: string }>;
}

export default async function BlogPostPage({ params }: Props) {
  const { slug } = await params;
  const { content, loading, error } = useContentBySlug('blog-post-content-type-id', slug);

  if (loading) return <div>Loading...</div>;
  if (error || !content) return notFound();

  return (
    <article>
      <h1>{content.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: content.data.content }} />
    </article>
  );
}
```

## Available Hooks

### `useContentTypes()`
Fetch all content types for your project.

### `useContentType(id: string)`
Fetch a specific content type by ID.

### `useContent(contentTypeId: string, params?: QueryParams)`
Fetch content items with optional filtering and pagination.

### `useContentItem(contentTypeId: string, id: string)`
Fetch a specific content item by ID.

### `useContentBySlug(contentTypeId: string, slug: string)`
Fetch a content item by its slug.

## Direct SDK Usage

You can also use the SDK directly without hooks:

```tsx
import LaunchlySitesSDK from '@launchlysites/nextjs-sdk';

const sdk = new LaunchlySitesSDK({
  apiUrl: 'https://your-cms-domain.com',
  projectId: 'your-project-id',
  apiKey: 'your-api-key',
});

// Fetch content
const content = await sdk.getContent('content-type-id');

// Search content
const results = await sdk.searchContent('search query');

// Upload media
const file = new File(['...'], 'image.jpg');
const media = await sdk.uploadMedia(file);
```

## Server-Side Rendering

For SSR, use the SDK directly in server components or API routes:

```tsx
// app/blog/page.tsx (Server Component)
import LaunchlySitesSDK from '@launchlysites/nextjs-sdk';

const sdk = new LaunchlySitesSDK({
  apiUrl: process.env.NEXT_PUBLIC_LAUNCHLY_API_URL!,
  projectId: process.env.NEXT_PUBLIC_LAUNCHLY_PROJECT_ID!,
  apiKey: process.env.LAUNCHLY_API_KEY,
});

export default async function BlogPage() {
  const { data: posts } = await sdk.getContent('blog-post-content-type-id', {
    status: 'published',
  });

  return (
    <div>
      <h1>Blog Posts</h1>
      {posts.map((post) => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.data.excerpt}</p>
        </article>
      ))}
    </div>
  );
}
```

## TypeScript Support

The SDK is fully typed. You can extend the types for your specific content:

```tsx
interface BlogPost extends Content {
  data: {
    content: string;
    excerpt: string;
    featured_image: string;
    author: string;
  };
}

const { content } = useContent<BlogPost>('blog-post-content-type-id');
```

## License

MIT