Skip to content

Media & Blocks

This page documents the MediaFile and BlocksContent types generated for Strapi media attributes and the Blocks rich text editor.

MediaFile

The MediaFile interface is generated for all Strapi media attributes. It represents a single uploaded file with its metadata.

ts
export interface MediaFile {
    id: number
    name: string
    alternativeText: string | null
    caption: string | null
    width: number | null
    height: number | null
    formats: unknown
    hash: string
    ext: string
    mime: string
    size: number
    url: string
    previewUrl: string | null
    provider: string
    createdAt: string
    updatedAt: string
}

Field Reference

FieldTypeDescription
idnumberDatabase ID of the media entry
namestringOriginal file name
alternativeTextstring | nullAlt text for accessibility
captionstring | nullOptional caption
widthnumber | nullImage width in pixels (null for non-images)
heightnumber | nullImage height in pixels (null for non-images)
formatsunknownResponsive image formats generated by Strapi (thumbnail, small, medium, large)
hashstringUnique hash of the file
extstringFile extension (e.g., .jpg, .pdf)
mimestringMIME type (e.g., image/jpeg, application/pdf)
sizenumberFile size in kilobytes
urlstringURL to access the file
previewUrlstring | nullPreview URL (used by some providers)
providerstringStorage provider (e.g., local, aws-s3, cloudinary)
createdAtstringISO datetime of upload
updatedAtstringISO datetime of last update

Single vs. Multiple Media

Strapi media attributes can be configured as single or multiple:

ConfigurationBase TypeInput Type
Single media (required)MediaFilenumber | null
Single media (not required)MediaFile | nullnumber | null
Multiple mediaMediaFile[]number[] | null

Using Media with Populate

Media fields require populate to be included in the response. Without populate, media fields are not present on the returned type.

ts
// Without populate — no media fields in the type
const article = await strapi.articles.findOne('abc123')
// article.cover  <-- does not exist on type

// With populate — media fields are included
const article = await strapi.articles.findOne('abc123', {
    populate: { cover: true },
})
// article.cover?.url  <-- fully typed as MediaFile | null

You can also select specific media fields:

ts
const article = await strapi.articles.findOne('abc123', {
    populate: {
        cover: { fields: ['url', 'alternativeText', 'width', 'height'] },
    },
})

Accessing Image URLs and Formats

ts
const article = await strapi.articles.findOne('abc123', {
    populate: { cover: true },
})

if (article.cover) {
    // Direct URL
    const imageUrl = article.cover.url

    // Alt text for <img> tag
    const alt = article.cover.alternativeText ?? ''

    // Dimensions
    const { width, height } = article.cover

    // Responsive formats (thumbnail, small, medium, large)
    const formats = article.cover.formats as Record<
        string,
        {
            url: string
            width: number
            height: number
        }
    > | null

    if (formats?.thumbnail) {
        const thumbnailUrl = formats.thumbnail.url
    }
}

TIP

The formats field is typed as unknown because its structure depends on your Strapi media configuration. Cast it to a more specific type if you know your format settings.

Media in Input Types

When creating or updating entries, media fields accept numeric IDs (not file objects). Upload the file first via Strapi's upload API, then reference it by ID.

ts
// Create with media by ID
await strapi.articles.create({
    title: 'New Article',
    cover: 42, // single media -> number
    gallery: [42, 43], // multiple media -> number[]
})

// Clear a media field
await strapi.articles.update('abc123', {
    cover: null,
})

BlocksContent

The BlocksContent type represents content from Strapi's Blocks rich text editor (the v2 rich text field introduced in Strapi v5). It is a structured array of block objects.

ts
export type BlocksContent = Block[]

Block Types

ts
export type Block =
    | ParagraphBlock
    | HeadingBlock
    | QuoteBlock
    | CodeBlock
    | ListBlock
    | ImageBlock

ParagraphBlock

ts
export interface ParagraphBlock {
    type: 'paragraph'
    children: InlineNode[]
}

HeadingBlock

ts
export interface HeadingBlock {
    type: 'heading'
    level: 1 | 2 | 3 | 4 | 5 | 6
    children: InlineNode[]
}

QuoteBlock

ts
export interface QuoteBlock {
    type: 'quote'
    children: InlineNode[]
}

CodeBlock

ts
export interface CodeBlock {
    type: 'code'
    language?: string
    children: InlineNode[]
}

ListBlock

ts
export interface ListBlock {
    type: 'list'
    format: 'ordered' | 'unordered'
    children: ListItemBlock[]
}

export interface ListItemBlock {
    type: 'list-item'
    children: InlineNode[]
}

ImageBlock

ts
export interface ImageBlock {
    type: 'image'
    image: {
        name: string
        alternativeText?: string | null
        url: string
        caption?: string | null
        width?: number
        height?: number
        formats?: unknown
        hash: string
        ext: string
        mime: string
        size: number
        previewUrl?: string | null
        provider: string
        createdAt: string
        updatedAt: string
    }
    children: InlineNode[]
}

Inline Nodes

All block types contain children arrays of inline nodes:

ts
export type InlineNode = TextNode | LinkInline

TextNode

ts
export interface TextNode {
    type: 'text'
    text: string
    bold?: boolean
    italic?: boolean
    underline?: boolean
    strikethrough?: boolean
    code?: boolean
}

LinkInline

ts
export interface LinkInline {
    type: 'link'
    url: string
    children: TextNode[]
}

Rendering Blocks on the Frontend

BlocksContent is a structured data format. You need a renderer to convert it to HTML or React elements. Strapi provides an official renderer for React:

bash
npm install @strapi/blocks-react-renderer
tsx
import { BlocksRenderer } from '@strapi/blocks-react-renderer'
import type { BlocksContent } from './dist'

function ArticleBody({ content }: { content: BlocksContent }) {
    return <BlocksRenderer content={content} />
}

INFO

The BlocksContent type is only generated when your schema contains at least one blocks type attribute. If your Strapi project uses only the classic richtext (Markdown) type, that field is typed as string instead.

Blocks vs. RichText

Attribute TypeGenerated TypeScript TypeFormat
richtext (Markdown)stringRaw Markdown string
blocks (Blocks editor)BlocksContentStructured JSON array

The blocks type provides a structured, renderable format, while richtext is a plain Markdown string that you parse and render yourself.

Released under the MIT License.