npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@multidots/sanity-blog-theme

v0.0.4

Published

Sanity Blog Theme by Multidots

Readme

Sanity Blog Theme (Next.js + Sanity v3)

Modern, editor-friendly starter that pairs Next.js (App Router) with Sanity Studio v3. It ships with a flexible Page Builder, a blog, SEO fields, and a curated Studio experience (Desk structure, grouped fields, icons, and collapsible inputs).

Highlights

  • Page Builder with reusable blocks (Hero, CTA, Image & Text, Client Logos, Services, Testimonials, Team, Address)
  • Organized editor UX: field groups, collapsible sections, sensible defaults, previews
  • Sanity Studio embedded at /studio with a custom content structure
  • Blog with authors, categories, SEO, pagination-ready queries

Create a new project

The easiest way to get started is using the CLI:

npx @multidots/sanity-blog-theme my-blog-project
cd my-blog-project

Or using your preferred package manager:

# npm
npx @multidots/sanity-blog-theme my-blog-project

# yarn
yarn create @multidots/sanity-blog-theme my-blog-project

# pnpm
pnpm create @multidots/sanity-blog-theme my-blog-project

or Directly clone the repository:

git clone https://github.com/multidots/sanity-blog.git
cd sanity-blog-theme

This will:

  • Create a new directory with your project name
  • Copy all template files
  • Interactive Sanity setup - Configure your project with guided prompts
  • Auto-generate .env.local - No manual environment setup needed
  • Install dependencies automatically
  • Set up a proper .gitignore file
  • Update package.json with your project name

🚀 Interactive Setup Process

The CLI will guide you through:

  1. Sanity Project Configuration - Enter your project details:

    • Project ID
    • Dataset name (default: "production")
    • API version (auto-suggested with current date)
  2. Environment File Creation - Choose to:

    • Create .env.local with your actual project details
    • Or get an .env.example template for manual setup
  3. Ready to Go - Your project will be fully configured and ready to run!

Project structure

Folder Structure

sanity-blog-theme/
├── public/                         # Static assets
│   └── images/                    # Image assets
├── src/                           # Source code
│   ├── app/                       # Next.js App Router
│   │   ├── (frontend)/           # Frontend route group
│   │   │   ├── [slug]/           # Dynamic page routes
│   │   │   └── blog/             # Blog routes
│   │   │       └── [slug]/       # Individual blog post routes
│   │   ├── api/                  # API routes
│   │   │   └── submit-form/      # Form submission endpoint for contact form plugin integration
│   │   └── studio/               # Sanity Studio routes
│   │       └── [[...tool]]/      # Studio catch-all routes
│   ├── components/               # React components
│   │   └── blocks/               # Page Builder block components
│   └── sanity/                   # Sanity configuration and schemas
│       ├── lib/                  # Sanity utilities
│       └── schemaTypes/          # Content schemas
│           └── blocks/           # Block schemas for Page Builder

Sanity Studio

  • Config: sanity.config.ts
  • Schemas: src/sanity/schemaTypes/
  • Custom Desk structure: src/sanity/structure.ts
  • Contact Form: @multidots/sanity-plugin-contact-form integration

Studio is mounted at /studio via the Next.js App Router integration.

Content model (schemas)

Documents

  • page: Title, Slug, Content (Page Builder), SEO
  • post: Title, Slug, Author, Main Image, Categories, Published At, Body, SEO
  • author: Name, Slug, Image, Bio
  • category: Title, Slug, Description
  • siteSettings (singleton): General, Header (Logo, Menu), Footer (menus, social), Blog settings, Home page reference

Objects and blocks

  • pageBuilder: Array composing these blocks:
    • hero: Headline/subtitle, background (image/color), alignment, colors
    • ctaBlock: Heading, Subheading, Button (text/link/new tab), background (image/color), text color
    • imageTextSection: Title, portable description, main image (+alt/size), image position, button
    • clientList: Title, logos (image + url/new tab)
    • services: Title, services (title, text, background color)
    • testimonialSlider: Title, testimonials (quote, author)
    • team: Title, team (name, role, image, bg color)
    • address: Title, address, phone, email
  • blockContent: Portable Text with basic marks, images, CTAs, etc.
  • seo: Title override, description, image, noindex

Icons

  • Blocks use icons from @sanity/icons for a clearer insert menu and arrays.
    • For example: hero (TextIcon), ctaBlock (BlockContentIcon), team (UsersIcon), address (PinIcon)
    • Change icons in each block schema under src/sanity/schemaTypes/blocks/*Type.ts.

Desk structure

Defined in src/sanity/structure.ts:

  • Site Settings singleton pinned at the top
  • Pages
  • Blog → Posts, Categories, Authors
  • Any other types appear in a fallback list

Frontend implementation

Rendering content

  • Page Builder component: src/components/PageBuilder.tsx
    • Maps each _type in the pageBuilder array to a React component in src/components/blocks/*
    • Includes in-place editing data attributes via next-sanity for a smoother authoring workflow

Mobile Navigation

  • Responsive hamburger menu with smooth slide animations
  • Vertical mobile menu layout with professional styling
  • Touch-friendly interactions and accessibility features
  • Auto-close on navigation and click outside

Contact Form System

  • Plugin: @multidots/sanity-plugin-contact-form v1.0.5
  • Features: Dynamic forms, file upload, reCAPTCHA, email notifications
  • Documentation: Plugin Documentation

Queries

Queries live in src/sanity/lib/queries.ts and cover header/footer, sitemap, pages, posts, and settings.

  • PAGE_QUERY loads page content + SEO
  • POSTS_QUERY, POSTS_COUNT_QUERY, SINGLE_POST_QUERY power the blog
  • SITE_SETTINGS_QUERY, HEADER_QUERY, FOOTER_QUERY load global UI config
  • SITEMAP_QUERY returns URLs and update dates for pages and posts

Using the Page Builder

  1. Create a Page document in Studio
  2. Add blocks to the Content group
  3. Use the insert menu (grid view) to discover blocks; re-order via drag-and-drop
  4. Most blocks have grouped fields (Content, Style, etc.) and collapsible sub-objects for a clean editing experience

Contact Form Plugin

The project includes @multidots/sanity-plugin-contact-form for dynamic form creation and management. For detailed setup and usage instructions, visit the plugin documentation.

Blog

Content modeling

  • post documents reference author and category
  • seo embedded per post

Frontend

  • Blog listing and post page live under src/app/(frontend)/blog
  • Pagination logic can use POSTS_QUERY + POSTS_COUNT_QUERY
  • Posts per page driven by siteSettings.blogPostsPerPage

Global settings

Singleton: siteSettings (enforced via Desk structure and restricted actions in sanity.config.ts).

Key fields

  • General: siteTitle
  • Header: logo, menuItems (title, url, openInNewTab)
  • Footer: footerTitle, footerDescription, footermenuItems, copyrightText, socialLinks
  • Pages: homePage reference (used as the site’s homepage source)
  • Blog: blogPostsPerPage, blogPageCTA

SEO

Each page and post has an seo object. Queries coalesce page/post title/description when SEO fields are left empty. noIndex can be toggled per document.

Add a new block

  1. Create the schema
  • Add a new file under src/sanity/schemaTypes/blocks/YourBlockType.ts
  • Follow the pattern in existing blocks: groups, fields, preview, icon
  1. Register the type
  • Export it from src/sanity/schemaTypes/index.ts
  • Add it to the of list in src/sanity/schemaTypes/pageBuilderType.ts
  1. Build the React component
  • Create src/components/blocks/YourBlock.tsx
  • Match props to your schema fields
  1. Map it in the Page Builder
  • Update the switch in src/components/PageBuilder.tsx to render your component when _type === 'yourBlock'
  1. (Optional) Insert menu preview
  • Add /public/block-previews/yourBlock.png to visualize the block in the Studio insert grid

Current Available Blocks: hero, ctaBlock, imageTextSection, clientList, services, testimonialSlider, team, address

Development

Common commands

npm run dev      # Start Next.js app + Studio (mounted at /studio)
npm run build    # Production build
npm run start    # Start production server

Sanity configuration

  • Project/API vars are set via src/sanity/env.ts
  • Studio plugins: Structure tool, Vision, Color input, Contact Form plugin

Troubleshooting

  • Missing env var error
    • The app throws a helpful error if NEXT_PUBLIC_SANITY_PROJECT_ID or NEXT_PUBLIC_SANITY_DATASET is missing
  • Studio not showing a type
    • Ensure the type is exported in src/sanity/schemaTypes/index.ts

License

MIT — feel free to use, modify, and distribute. Attribution is appreciated.