New:Microsoft Teams Notifications Are Now Available in Socket.Learn more
Get Started

pressroom

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pressroom

Type-safe content collections for Next.js.

latest
Source
npmnpm
Version
0.1.0
Version published
Weekly downloads
1
-83.33%
Maintainers
1
Weekly downloads
 
Created
Source

pressroom

Type-safe content collections for Next.js.

Like Astro content collections, but for Next.js -- define schemas, drop in Markdown/MDX/JSON/YAML files, and query them with full TypeScript inference.

Install

npm install pressroom

Quick Start

1. Define your collections

// lib/pressroom.ts
import { createPressroom } from "pressroom";

export const pressroom = createPressroom({
  posts: {
    schema: {
      title: "string",
      date: "date",
      draft: { type: "boolean", required: false, default: false },
      tags: "array",
    },
    directory: "./content/posts",
    format: "md",
  },
  authors: {
    schema: {
      name: { type: "string", required: true },
      avatar: "image",
      bio: "string",
    },
    directory: "./content/authors",
    format: "json",
  },
});

2. Create content files

<!-- content/posts/hello-world.md -->
---
title: Hello World
date: 2026-01-15
tags:
  - intro
  - blog
---

Welcome to my blog. This is the first post.

3. Query in your pages

// app/blog/page.tsx
import { pressroom } from "@/lib/pressroom";

export default async function BlogIndex() {
  const posts = await pressroom
    .collection("posts")
    .query()
    .where("draft", "eq", false)
    .sort("date", "desc")
    .exec();

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.slug}>
          <a href={`/blog/${post.slug}`}>{post.data.title}</a>
        </li>
      ))}
    </ul>
  );
}

Collection Schemas

Each field in a schema can be a shorthand type string or a full definition:

const schema = {
  // Shorthand
  title: "string",
  count: "number",
  published: "boolean",
  createdAt: "date",
  tags: "array",
  metadata: "object",
  cover: "image",
  urlSlug: "slug",

  // Full definition with validation
  email: {
    type: "string",
    required: true,
    validate: (v) => String(v).includes("@") || "Must be a valid email",
  },

  // With defaults
  draft: {
    type: "boolean",
    required: false,
    default: false,
  },
};

Field Types

TypeTypeScriptDescription
stringstringText value
numbernumberNumeric value (auto-coerced)
booleanbooleanTrue/false (auto-coerced)
dateDateDate object (auto-coerced)
arrayunknown[]Array of values
objectRecordNested object
imagestringImage path/URL
slugstringURL-safe identifier

Content Formats

Set format in your collection config:

  • "md" (default) -- Markdown with YAML frontmatter
  • "mdx" -- MDX with YAML frontmatter
  • "json" -- JSON files (entire file is data, no body content)
  • "yaml" -- YAML files (entire file is data, no body content)

Querying

Basic Methods

const collection = pressroom.collection("posts");

// Get all entries
const all = await collection.getAll();

// Get by slug (filename without extension)
const post = await collection.getBySlug("hello-world");

// With options
const recent = await collection.getAll({
  sort: { field: "date", order: "desc" },
  limit: 10,
});

Fluent Query Builder

const results = await pressroom
  .collection("posts")
  .query()
  .where("draft", "eq", false)
  .where("tags", "contains", "tutorial")
  .sort("date", "desc")
  .limit(5)
  .offset(10)
  .exec();

Filter Operators

OperatorDescription
eqEqual
neqNot equal
gtGreater than
gteGreater than or equal
ltLess than
lteLess than or equal
inValue is in array
containsString/array contains

React Components

import { Markdown, ContentList, PressroomProvider, usePressroom } from "pressroom/react";

Markdown Renderer

Renders a markdown string to React elements. Supports headings, paragraphs, bold, italic, inline code, links, images, code blocks, and lists.

<Markdown content={post.content} className="prose" />

ContentList

<ContentList
  entries={posts}
  renderItem={(post) => (
    <article key={post.slug}>
      <h2>{post.data.title}</h2>
    </article>
  )}
/>

Context Provider

// In a client layout
<PressroomProvider pressroom={pressroom}>
  <App />
</PressroomProvider>

// In a child component
function PostList() {
  const pr = usePressroom();
  // ...
}

Next.js Integration

import { generateStaticParams, getStaticContent, createContentHandler } from "pressroom/next";

Static Params (for [slug] routes)

// app/blog/[slug]/page.tsx
import { pressroom } from "@/lib/pressroom";
import { generateStaticParams as genParams } from "pressroom/next";

export async function generateStaticParams() {
  return genParams(pressroom, "posts");
}

Server Component Helper

import { getStaticContent } from "pressroom/next";

export default async function PostPage({ params }: { params: { slug: string } }) {
  const post = await getStaticContent(pressroom, "posts", params.slug);
  if (!post) return <div>Not found</div>;
  return <article>{post.data.title}</article>;
}

API Route Handler

// app/api/content/[collection]/route.ts
import { createContentHandler } from "pressroom/next";
import { pressroom } from "@/lib/pressroom";

export const GET = createContentHandler(pressroom);

Query via URL params:

GET /api/content/posts?sort=date&order=desc&limit=10
GET /api/content/posts?slug=hello-world
GET /api/content/posts?where.draft.eq=false

Directory Structure

your-project/
├── content/
│   ├── posts/
│   │   ├── hello-world.md
│   │   └── second-post.md
│   └── authors/
│       ├── alice.json
│       └── bob.json
├── lib/
│   └── pressroom.ts          # createPressroom config
├── app/
│   ├── blog/
│   │   ├── page.tsx           # List page
│   │   └── [slug]/
│   │       └── page.tsx       # Detail page
│   └── api/
│       └── content/
│           └── [collection]/
│               └── route.ts   # Optional API
└── package.json

License

MIT

Keywords

cms

FAQs

Package last updated on 27 Mar 2026

Related posts