# RSS Feed Item

> RSS/Atom feed and item with title, link, enclosure, and categories.

- Name: `rss-feed-item`
- Categories: social
- Detail page: https://open-types.dev/types/rss-feed-item

## Install

```bash
# Types only
npx shadcn add @open-types/rss-feed-item

# Types + Zod v4 validators
npx shadcn add @open-types/rss-feed-item-zod

# Types + real-world examples
npx shadcn add @open-types/rss-feed-item-examples
```

## Types

```typescript
export interface RSSEnclosure {
  url: string;
  type: string;
  length?: number;
}

export interface RSSFeedItem {
  title?: string;
  link?: string;
  description?: string;
  pubDate?: string;
  guid?: string;
  author?: string;
  categories?: string[];
  enclosure?: RSSEnclosure;
}

export interface RSSFeed {
  title: string;
  link: string;
  description: string;
  language?: string;
  items: RSSFeedItem[];
}
```

## Zod validator

```typescript
import * as z from "zod";
import type { RSSFeed, RSSFeedItem, RSSEnclosure } from "../types/rss-feed-item";

export const rssEnclosureSchema = z.object({
  url: z.url({ error: "Enclosure URL must be a valid URL" }),
  type: z.string().min(1, { error: "Enclosure type is required" }),
  length: z.number().int({ error: "Enclosure length must be a whole number" }).min(0, {
    error: "Enclosure length cannot be negative",
  }).optional(),
}) satisfies z.ZodType<RSSEnclosure>;

export const rssFeedItemSchema = z.object({
  title: z.string().optional(),
  link: z.url({ error: "Item link must be a valid URL" }).optional(),
  description: z.string().optional(),
  pubDate: z.string().optional(),
  guid: z.string().optional(),
  author: z.string().optional(),
  categories: z.array(z.string().min(1, { error: "Category cannot be empty" })).optional(),
  enclosure: rssEnclosureSchema.optional(),
}) satisfies z.ZodType<RSSFeedItem>;

export const rssFeedSchema = z.object({
  title: z.string().min(1, { error: "Feed title is required" }),
  link: z.url({ error: "Feed link must be a valid URL" }),
  description: z.string().min(1, { error: "Feed description is required" }),
  language: z.string().optional(),
  items: z.array(rssFeedItemSchema),
}) satisfies z.ZodType<RSSFeed>;

export type { RSSFeed, RSSFeedItem, RSSEnclosure } from "../types/rss-feed-item";
```

## Examples

```typescript
// Source: https://www.rssboard.org/rss-specification
// Captured: 2026-05
import type {
  RSSEnclosure,
  RSSFeedItem,
  RSSFeed,
} from "../types/rss-feed-item";

const podcastEnclosure = {
  url: "https://cdn.example.com/podcasts/ep42.mp3",
  type: "audio/mpeg",
  length: 18_350_000,
} as const satisfies RSSEnclosure;

export const rssEnclosureExamples = {
  podcast: podcastEnclosure,
  videoNoLength: {
    url: "https://cdn.example.com/videos/intro.mp4",
    type: "video/mp4",
  } satisfies RSSEnclosure,
  image: {
    url: "https://cdn.example.com/images/cover.jpg",
    type: "image/jpeg",
    length: 92_341,
  } satisfies RSSEnclosure,
} as const;

const blogItem = {
  title: "Why we built OpenTypes",
  link: "https://open-types.dev/blog/why",
  description: "A community-curated registry of TypeScript types for everyday data shapes.",
  pubDate: "Fri, 16 May 2026 18:30:00 +0000",
  guid: "https://open-types.dev/blog/why",
  author: "marco@open-types.dev (Marco Tisi)",
  categories: ["typescript", "registry", "announcements"],
} as const satisfies RSSFeedItem;

export const rssFeedItemExamples = {
  blogPost: blogItem,
  podcastEpisode: {
    title: "Episode 42: Type design",
    link: "https://open-types.dev/podcast/42",
    description: "Designing types for the open web.",
    pubDate: "Fri, 16 May 2026 18:30:00 +0000",
    guid: "ep-42-2026-05-16",
    enclosure: podcastEnclosure,
  } satisfies RSSFeedItem,
  minimal: { title: "Untitled" } satisfies RSSFeedItem,
  empty: {} satisfies RSSFeedItem,
} as const;

export const rssFeedExamples = {
  blog: {
    title: "OpenTypes Blog",
    link: "https://open-types.dev/blog",
    description: "Updates from the OpenTypes registry.",
    language: "en-US",
    items: [blogItem, rssFeedItemExamples.podcastEpisode],
  } satisfies RSSFeed,
  empty: {
    title: "OpenTypes Blog",
    link: "https://open-types.dev/blog",
    description: "Updates from the OpenTypes registry.",
    items: [],
  } satisfies RSSFeed,
} as const;
```
