> ## Documentation Index
> Fetch the complete documentation index at: https://docs.strapi2front.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Generated Types

> Understanding the TypeScript interfaces and types generated from your Strapi schema

strapi2front generates complete TypeScript type definitions from your Strapi content types, providing full type safety for your frontend application.

## What Gets Generated

When you run `npx strapi2front sync`, the generator creates:

<CardGroup cols={2}>
  <Card title="Collection Types" icon="layer-group">
    TypeScript interfaces with full type safety for all your collection types
  </Card>

  <Card title="Single Types" icon="file">
    Interfaces for single types like homepage, settings, etc.
  </Card>

  <Card title="Components" icon="puzzle-piece">
    Reusable component interfaces referenced by your content types
  </Card>

  <Card title="Utility Types" icon="toolbox">
    Helper types for media, pagination, responses, and more
  </Card>
</CardGroup>

## Generated File Structure

```
src/strapi/
├── collections/
│   ├── article.ts
│   ├── category.ts
│   └── author.ts
├── components/
│   ├── seo.ts
│   └── content-block.ts
└── utils.ts
```

## Collection Type Example

For a **Blog Article** collection type in Strapi, the generator creates:

<CodeGroup>
  ```typescript article.ts theme={null}
  /**
   * Article
   * Blog article with author and categories
   * Generated by strapi2front
   */

  import type { StrapiBaseEntity, StrapiMedia, BlocksContent } from '../utils';
  import type { Author } from './author';
  import type { Category } from './category';
  import type { Seo } from '../components/seo';

  export interface Article extends StrapiBaseEntity {
    /** Required, Min length: 1, Max length: 255 */
    title: string;
    
    slug: string;
    
    /** Rich text content (Strapi v5) */
    content: BlocksContent;
    
    excerpt?: string;
    
    coverImage: StrapiMedia | null;
    
    /** Published status */
    status: 'draft' | 'published' | 'archived';
    
    /** View count */
    views: number;
    
    /** Reading time in minutes */
    readingTime?: number;
    
    /** Article author */
    author: Author | null;
    
    /** Article categories */
    categories: Category[];
    
    /** SEO metadata */
    seo?: Seo | null;
  }

  export interface ArticleFilters {
    id?: number | { $eq?: number; $ne?: number; $in?: number[]; $notIn?: number[] };
    documentId?: string | { $eq?: string; $ne?: string };
    title?: string | { $eq?: string; $contains?: string };
    status?: 'draft' | 'published' | 'archived';
    createdAt?: string | { $eq?: string; $gt?: string; $gte?: string; $lt?: string; $lte?: string };
    publishedAt?: string | null | { $eq?: string; $ne?: string; $null?: boolean };
    $and?: ArticleFilters[];
    $or?: ArticleFilters[];
    $not?: ArticleFilters;
  }

  export interface ArticleSort {
    field: keyof Article;
    order: 'asc' | 'desc';
  }
  ```

  ```typescript Single Type Example theme={null}
  /**
   * Homepage (Single Type)
   * Main homepage configuration
   * Generated by strapi2front
   */

  import type { StrapiBaseEntity, StrapiMedia } from '../utils';
  import type { Hero } from '../components/hero';

  export interface Homepage extends StrapiBaseEntity {
    /** Page title */
    title: string;
    
    /** Hero section */
    hero: Hero | null;
    
    /** Featured content */
    featuredArticles: Article[];
    
    /** Open graph image */
    ogImage: StrapiMedia | null;
  }
  ```
</CodeGroup>

## Attribute Type Mappings

strapi2front maps Strapi field types to TypeScript types:

<Tabs>
  <Tab title="Basic Types">
    | Strapi Type  | TypeScript Type | Example                       |
    | ------------ | --------------- | ----------------------------- |
    | `string`     | `string`        | `title: string`               |
    | `text`       | `string`        | `description: string`         |
    | `richtext`   | `string`        | `content: string` (v4)        |
    | `blocks`     | `BlocksContent` | `content: BlocksContent` (v5) |
    | `email`      | `string`        | `email: string`               |
    | `password`   | `string`        | `password: string`            |
    | `uid`        | `string`        | `slug: string`                |
    | `integer`    | `number`        | `views: number`               |
    | `biginteger` | `number`        | `largeNumber: number`         |
    | `float`      | `number`        | `rating: number`              |
    | `decimal`    | `number`        | `price: number`               |
    | `boolean`    | `boolean`       | `featured: boolean`           |
    | `date`       | `string`        | `publishDate: string`         |
    | `datetime`   | `string`        | `publishedAt: string`         |
    | `time`       | `string`        | `eventTime: string`           |
    | `json`       | `unknown`       | `metadata: unknown`           |
  </Tab>

  <Tab title="Advanced Types">
    | Strapi Type              | TypeScript Type         | Example                                |
    | ------------------------ | ----------------------- | -------------------------------------- |
    | `enumeration`            | Union of literals       | `status: 'draft' \| 'published'`       |
    | `media` (single)         | `StrapiMedia \| null`   | `cover: StrapiMedia \| null`           |
    | `media` (multiple)       | `StrapiMedia[]`         | `gallery: StrapiMedia[]`               |
    | `relation` (to-one)      | `RelatedType \| null`   | `author: Author \| null`               |
    | `relation` (to-many)     | `RelatedType[]`         | `tags: Tag[]`                          |
    | `component`              | `ComponentType \| null` | `seo: Seo \| null`                     |
    | `component` (repeatable) | `ComponentType[]`       | `sections: Section[]`                  |
    | `dynamiczone`            | `(CompA \| CompB)[]`    | `content: (TextBlock \| ImageBlock)[]` |
  </Tab>
</Tabs>

## Utility Types

The generator also creates utility types in `utils.ts`:

<Accordion title="StrapiBaseEntity">
  Base interface that all content types extend. Contains system fields.

  <CodeGroup>
    ```typescript Strapi v5 theme={null}
    export interface StrapiBaseEntity {
      id: number;
      documentId: string;  // New in v5
      createdAt: string;
      updatedAt: string;
      publishedAt: string | null;
    }
    ```

    ```typescript Strapi v4 theme={null}
    export interface StrapiBaseEntity {
      id: number;
      createdAt: string;
      updatedAt: string;
      publishedAt: string | null;
    }
    ```
  </CodeGroup>
</Accordion>

<Accordion title="StrapiMedia">
  Type definition for media files (images, videos, etc.)

  ```typescript theme={null}
  export interface StrapiMedia {
    id: number;
    documentId: string;  // v5 only
    name: string;
    alternativeText: string | null;
    caption: string | null;
    width: number;
    height: number;
    formats: {
      thumbnail?: StrapiMediaFormat;
      small?: StrapiMediaFormat;
      medium?: StrapiMediaFormat;
      large?: StrapiMediaFormat;
    } | null;
    hash: string;
    ext: string;
    mime: string;
    size: number;
    url: string;
    previewUrl: string | null;
    provider: string;
    createdAt: string;
    updatedAt: string;
  }

  export interface StrapiMediaFormat {
    name: string;
    hash: string;
    ext: string;
    mime: string;
    width: number;
    height: number;
    size: number;
    url: string;
  }
  ```
</Accordion>

<Accordion title="BlocksContent (Strapi v5)">
  Rich text blocks for Strapi v5's new blocks editor.

  <Info>
    For full type support and rendering, install `@strapi/blocks-react-renderer` then re-run `npx strapi2front sync`.
  </Info>

  ```typescript theme={null}
  // With @strapi/blocks-react-renderer installed
  export type { BlocksContent } from '@strapi/blocks-react-renderer';

  // Without package (fallback)
  export type BlocksContent = unknown[];
  ```
</Accordion>

<Accordion title="StrapiResponse & StrapiListResponse">
  Wrapper types for API responses with metadata.

  ```typescript theme={null}
  export interface StrapiResponse<T> {
    data: T;
    meta: {
      pagination?: StrapiPagination;
    };
  }

  export interface StrapiListResponse<T> {
    data: T[];
    meta: {
      pagination: StrapiPagination;
    };
  }

  export interface StrapiPagination {
    page: number;
    pageSize: number;
    pageCount: number;
    total: number;
  }
  ```
</Accordion>

## Using Generated Types

### Import Types in Your Components

```typescript pages/blog/[slug].astro theme={null}
import type { Article } from '@/strapi/collections/article';
import { articleService } from '@/strapi/collections/article/service';

const { slug } = Astro.params;
const article = await articleService.findBySlug(slug);

// TypeScript knows the exact shape of 'article'
const title: string = article.title;
const coverUrl: string | null = article.coverImage?.url ?? null;
```

### Type-Safe Data Fetching

```typescript utils/blog.ts theme={null}
import type { Article, ArticleFilters } from '@/strapi/collections/article';
import { articleService } from '@/strapi/collections/article/service';

export async function getFeaturedArticles(): Promise<Article[]> {
  const filters: ArticleFilters = {
    status: 'published',
    featured: true,
  };
  
  const { data } = await articleService.findMany({
    filters,
    sort: ['-publishedAt'],
    pagination: { pageSize: 6 },
  });
  
  return data;
}
```

### Working with Relations

```typescript components/ArticleCard.tsx theme={null}
import type { Article } from '@/strapi/collections/article';

interface Props {
  article: Article;
}

export function ArticleCard({ article }: Props) {
  // TypeScript knows author is Author | null
  const authorName = article.author?.name ?? 'Anonymous';
  
  // TypeScript knows categories is Category[]
  const categoryNames = article.categories.map(cat => cat.name);
  
  return (
    <div>
      <h2>{article.title}</h2>
      <p>By {authorName}</p>
      <div>{categoryNames.join(', ')}</div>
    </div>
  );
}
```

## Field Validation Attributes

The generator includes validation constraints from your Strapi schema as JSDoc comments:

```typescript theme={null}
export interface Product extends StrapiBaseEntity {
  /** Required, Min length: 3, Max length: 100 */
  name: string;
  
  /** Min: 0, Max: 999999 */
  price: number;
  
  /** Required, Min length: 10 */
  description: string;
}
```

## Dynamic Zones

For dynamic zones (flexible content areas), the generator creates discriminated unions:

```typescript theme={null}
import type { TextBlock } from '../components/text-block';
import type { ImageBlock } from '../components/image-block';
import type { VideoBlock } from '../components/video-block';

export interface Page extends StrapiBaseEntity {
  title: string;
  
  // Dynamic zone with multiple component types
  content: (TextBlock | ImageBlock | VideoBlock)[];
}
```

You can use TypeScript's type narrowing:

```typescript theme={null}
function renderContent(blocks: (TextBlock | ImageBlock | VideoBlock)[]) {
  return blocks.map(block => {
    // Check the __component field to narrow the type
    if (block.__component === 'content.text-block') {
      // TypeScript knows this is TextBlock
      return <TextRenderer text={block.text} />;
    }
    if (block.__component === 'content.image-block') {
      // TypeScript knows this is ImageBlock
      return <ImageRenderer image={block.image} />;
    }
    // etc...
  });
}
```

<Note>
  Types are automatically regenerated when you run `npx strapi2front sync`. Make sure to sync after changing your Strapi schema.
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="Services" icon="code" href="/guides/services">
    Learn how to use generated service functions for data fetching
  </Card>

  <Card title="Schemas" icon="shield-check" href="/guides/schemas">
    Validate form data with generated Zod schemas
  </Card>

  <Card title="Relations" icon="link" href="/guides/relations">
    Working with related content types
  </Card>

  <Card title="Media" icon="image" href="/guides/media">
    Handle images and file uploads
  </Card>
</CardGroup>
