# Stafflyn Next.js SEO Integration Guide

This guide explains how to integrate the Stafflyn backend SEO schema endpoints into your Next.js frontend application.

## 📋 Overview

The Stafflyn backend provides JSON-LD schema endpoints for SEO. This package provides TypeScript hooks and components to easily integrate them into your Next.js app.

### Available Endpoints

- **Blog Schema**: `GET /api/schema/blog/<slug>/` - Article schema for blog posts
- **Job Schema**: `GET /api/schema/job/<slug>/` - JobPosting schema for job listings
- **Organization Schema**: `GET /api/schema/organization/` - Organization schema for company info
- **Breadcrumb Schema**: `GET /api/schema/breadcrumb/?path=<path>` - BreadcrumbList schema

---

## 🚀 Setup

### 1. Copy the Integration Files

Copy `NEXT_JS_SEO_INTEGRATION.ts` to your Next.js project:

```bash
# Copy to your Next.js lib folder
cp NEXT_JS_SEO_INTEGRATION.ts your-nextjs-app/src/lib/stafflyn-seo.ts
```

### 2. Configure Environment Variables

Create or update `.env.local`:

```env
NEXT_PUBLIC_API_URL=http://localhost:8000/api
```

For production:

```env
NEXT_PUBLIC_API_URL=https://your-api-domain.com/api
```

### 3. Install Optional Dependencies (Recommended)

```bash
npm install next-seo
# or
yarn add next-seo
```

---

## 📖 Usage Examples

### Example 1: Blog Post Page

```typescript
// pages/blogs/[slug].tsx
import Head from 'next/head';
import { useBlogSchema, SchemaScript } from '@/lib/stafflyn-seo';

export default function BlogPage({ blog }) {
  const { schema } = useBlogSchema(blog.slug);

  return (
    <>
      <Head>
        <title>{blog.meta_title || blog.title}</title>
        <meta name="description" content={blog.meta_description} />
        <SchemaScript schema={schema} />
      </Head>

      <article>
        <h1>{blog.title}</h1>
        <p>Reading time: {blog.reading_time} minutes</p>
        <img src={blog.featured_image} alt={blog.featured_image_alt} />
        <div>{blog.content}</div>
      </article>
    </>
  );
}
```

### Example 2: Job Post Page

```typescript
// pages/jobs/[id].tsx
import Head from 'next/head';
import { useJobSchema, SchemaScript } from '@/lib/stafflyn-seo';

export default function JobPage({ job }) {
  const { schema } = useJobSchema(job.slug);

  return (
    <>
      <Head>
        <title>{job.meta_title || job.title}</title>
        <meta name="description" content={job.meta_description} />
        <SchemaScript schema={schema} />
      </Head>

      <div className="job-posting">
        <h1>{job.title}</h1>
        <p>{job.CompanyName} - {job.CompanyCountry}</p>
        <p>{job.requirements}</p>
      </div>
    </>
  );
}
```

### Example 3: Breadcrumb Navigation

```typescript
import { BreadcrumbComponent } from '@/lib/stafflyn-seo';
import { useRouter } from 'next/router';

export default function Layout({ children }) {
  const router = useRouter();

  return (
    <>
      <BreadcrumbComponent path={router.asPath} />
      {children}
    </>
  );
}
```

### Example 4: Global Organization Schema

```typescript
// pages/_app.tsx
import Head from 'next/head';
import { useOrganizationSchema, SchemaScript } from '@/lib/stafflyn-seo';

function MyApp({ Component, pageProps }) {
  const { schema: orgSchema } = useOrganizationSchema();

  return (
    <>
      <Head>
        <SchemaScript schema={orgSchema} />
      </Head>
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;
```

---

## 🎣 Available Hooks

### `useSchema<T>(endpoint: string, options?: { skip?: boolean })`

Generic hook to fetch any schema endpoint.

```typescript
const { schema, loading, error } = useSchema('/schema/blog/my-post/');

if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;

return <SchemaScript schema={schema} />;
```

### `useBlogSchema(slug: string)`

Fetch blog article schema.

```typescript
const { schema, loading } = useBlogSchema('my-blog-post');
```

### `useJobSchema(jobId: number | string)`

Fetch job posting schema.

```typescript
const { schema, loading } = useJobSchema(123);
```

### `useOrganizationSchema()`

Fetch organization schema.

```typescript
const { schema } = useOrganizationSchema();
```

### `useBreadcrumbSchema(path: string)`

Fetch breadcrumb schema for a path.

```typescript
const { schema } = useBreadcrumbSchema('/blogs/my-post');
```

---

## 🔧 Available Components

### `<SchemaScript schema={schema} />`

Injects JSON-LD schema into page head.

```typescript
<Head>
  <SchemaScript schema={schema} defer={true} />
</Head>
```

### `<BlogSchemaComponent slug={slug}>`

Wrapper component for blog schema injection.

```typescript
<BlogSchemaComponent slug="my-post">
  <article>Blog content here</article>
</BlogSchemaComponent>
```

### `<JobSchemaComponent jobId={id}>`

Wrapper component for job schema injection.

```typescript
<JobSchemaComponent jobId={123}>
  <div>Job content here</div>
</JobSchemaComponent>
```

### `<BreadcrumbComponent path={path} className="custom-class">`

Breadcrumb navigation with schema.

```typescript
<BreadcrumbComponent path="/blogs/my-post" className="mb-4" />
```

---

## 📊 Helper Functions

### `getMetaTagsFromSchema(schema)`

Extract meta tag data from schema.

```typescript
const { schema } = useBlogSchema(slug);
const meta = getMetaTagsFromSchema(schema);

// Returns:
// {
//   title: "Blog title",
//   description: "Meta description",
//   image: "image URL",
//   author: "Author name"
// }
```

---

## 🌐 With next-seo Package (Alternative)

If you prefer using the `next-seo` package, you can use their components directly:

```typescript
import { ArticleJsonLd } from 'next-seo';

export default function BlogPage({ blog }) {
  return (
    <>
      <ArticleJsonLd
        url={`https://stafflyn.com/blogs/${blog.slug}`}
        title={blog.title}
        images={[blog.featured_image]}
        datePublished={blog.published_at}
        dateModified={blog.updated_at}
        authorName={blog.author.name}
        description={blog.meta_description}
      />
      {/* Page content */}
    </>
  );
}
```

---

## ✅ Checklist for SEO Setup

- [ ] Copy `NEXT_JS_SEO_INTEGRATION.ts` to your project
- [ ] Configure `NEXT_PUBLIC_API_URL` in `.env.local`
- [ ] Update all blog pages to use `useBlogSchema` hook
- [ ] Update all job pages to use `useJobSchema` hook
- [ ] Add `<BreadcrumbComponent />` to your layout
- [ ] Add organization schema in `_app.tsx` or root layout
- [ ] Add meta titles and descriptions to all pages
- [ ] Test with Google Search Console
- [ ] Validate schemas with [Schema.org validator](https://validator.schema.org/)
- [ ] Monitor SEO performance with Google Analytics

---

## 🧪 Testing Schema Markup

### 1. Google's Rich Results Test

Go to: https://search.google.com/test/rich-results

Paste your page URL and check if schema is detected.

### 2. Schema.org Validator

Go to: https://validator.schema.org/

Paste your page HTML to validate schema markup.

### 3. Browser DevTools

Check the `<head>` tag for `<script type="application/ld+json">` elements.

---

## 🐛 Troubleshooting

### Schema not showing in page

**Solution**: Make sure you're using `<Head>` from `next/head` and the schema endpoint is returning data.

```typescript
import Head from 'next/head';
// Not from next/document
```

### API endpoint returns 404

**Solution**: Check that your backend is running and the slug/ID is correct.

```bash
# Test the API manually
curl http://localhost:8000/api/schema/blog/my-slug/
```

### Images not loading in schema

**Solution**: Ensure image URLs are absolute (start with `http://` or `https://`)

```typescript
// ❌ Wrong
"image": "/path/to/image.jpg"

// ✅ Correct
"image": "https://stafflyn.com/path/to/image.jpg"
```

### Reading time and word count not showing

**Solution**: Make sure you're fetching and displaying them:

```typescript
<p>📖 {blog.reading_time} min read</p>
<p>📝 {blog.word_count} words</p>
```

---

## 📚 Backend Endpoints Reference

### Blog Schema
```
GET /api/schema/blog/{slug}/
```

Response includes:
- `headline`, `description`
- `image` with URL and alt text
- `datePublished`, `dateModified`
- `author` info
- `wordCount`, `timeRequired` (reading time)
- `keywords` (from tags)

### Job Schema
```
GET /api/schema/job/{job_id}/
```

Response includes:
- `title`, `description`
- `hiringOrganization` (company info)
- `jobLocation` (country)
- `baseSalary` (if available)
- `datePosted`, `validThrough`
- `skills` (from Tags)

### Organization Schema
```
GET /api/schema/organization/
```

Response includes:
- `name`, `url`, `description`
- `logo`, `contactPoint`
- Social media links (sameAs)

### Breadcrumb Schema
```
GET /api/schema/breadcrumb/?path={url_path}
```

Response includes:
- `itemListElement` array with breadcrumb items
- Each item has `position`, `name`, and `item` (URL)

---

## 📝 Best Practices

1. **Always include meta descriptions** - They show in search results
2. **Use proper heading hierarchy** - H1 for page title, H2+ for sections
3. **Add alt text to images** - Use the `*_alt` fields
4. **Include word count and reading time** - Helps with user engagement metrics
5. **Test with Google Search Console** - See how Google sees your pages
6. **Update schemas when content changes** - Backend updates are automatic
7. **Use canonical URLs** - Prevent duplicate content issues

---

## 🎯 Next Steps

1. Integrate the helper into your Next.js project
2. Update all blog and job pages
3. Test with Google's tools
4. Monitor performance in Google Search Console
5. Iterate based on SEO metrics

---

## 📞 Support

For issues with:
- **Backend schemas**: Check the backend `/api/schema/*` endpoints
- **Next.js integration**: Review the NEXT_JS_USAGE_EXAMPLES.ts file
- **SEO best practices**: Visit https://developers.google.com/search

---

**Happy SEO optimization! 🚀**
