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

@ai-growth/nextjs

v1.3.1

Published

Seamlessly integrate Sanity CMS with Next.js applications for automated blog routing and rendering

Readme

@ai-growth/nextjs

npm version License: MIT TypeScript Next.js

Enterprise-grade Sanity CMS integration for Next.js with advanced SEO, performance optimization, and developer experience

🚀 Overview

@ai-growth/nextjs is a production-ready npm package that provides seamless integration between Sanity CMS and Next.js applications. It offers enterprise-level features including advanced SEO optimization, performance caching, lazy loading, comprehensive error handling, and responsive image optimization.

✨ Key Features:

  • 🚀 Rapid Setup: Zero-config integration with intelligent defaults
  • 🔄 Automatic Routing: Dynamic /cms/<slug> route handling
  • 🎨 Customizable Templates: Advanced template system with lazy loading
  • 📱 Responsive Design: Mobile-first, accessible, SEO-optimized
  • 🔧 TypeScript First: Complete type safety and IntelliSense support
  • Performance Optimized: Multi-layer caching, code splitting, image optimization
  • 🛡️ Error Resilient: Comprehensive error boundaries and fallback systems
  • 🔍 SEO Ready: Automatic meta tags, structured data, social media optimization
  • 📊 Developer Experience: Rich debugging tools and performance monitoring
  • 🔓 Optional API Token: No token needed for public data queries (CDN optimized)
  • 🌍 Flexible Environment Variables: Works with or without NEXT_PUBLIC_ prefix

📦 Installation

npm install @ai-growth/nextjs
# or
yarn add @ai-growth/nextjs
# or
pnpm add @ai-growth/nextjs

Required Peer Dependencies

npm install next@>=12.0.0 react@>=17.0.0 react-dom@>=17.0.0

Optional Dependencies

For enhanced features:

# For image optimization
npm install @sanity/image-url

# For advanced caching (already included)
# npm install @sanity/client

🚀 Quick Start

1. Environment Setup

Create .env.local in your project root:

# Required - Sanity Configuration
SANITY_PROJECT_ID=your_project_id
SANITY_DATASET=production
SANITY_API_TOKEN=your_api_token
SANITY_API_VERSION=2023-05-03

# Optional - Routing Configuration
CMS_ROUTE_PATH=/cms/

# Optional - Performance Configuration
ENABLE_CACHE=true
CACHE_TTL=300

2. Basic Integration

App Router (Next.js 13+)

// app/layout.tsx
import { CmsProvider } from '@ai-growth/nextjs';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <CmsProvider>
          {children}
        </CmsProvider>
      </body>
    </html>
  );
}

// app/[[...slug]]/page.tsx
import { CmsRouteHandler } from '@ai-growth/nextjs';

export default function DynamicPage() {
  return (
    <CmsRouteHandler>
      <div>This content shows for non-CMS routes</div>
    </CmsRouteHandler>
  );
}

Pages Router (Next.js 12+)

// pages/_app.tsx
import { CmsProvider } from '@ai-growth/nextjs';
import type { AppProps } from 'next/app';

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <CmsProvider>
      <Component {...pageProps} />
    </CmsProvider>
  );
}

// pages/[[...slug]].tsx
import { CmsRouteHandler } from '@ai-growth/nextjs';

export default function CatchAllPage() {
  return (
    <CmsRouteHandler>
      <div>Fallback content for non-CMS routes</div>
    </CmsRouteHandler>
  );
}

3. Advanced Configuration

// lib/cms-config.ts
import { CmsConfig } from '@ai-growth/nextjs';

export const cmsConfig: CmsConfig = {
  // Sanity Configuration
  projectId: process.env.SANITY_PROJECT_ID!,
  dataset: process.env.SANITY_DATASET!,
  apiToken: process.env.SANITY_API_TOKEN,
  apiVersion: process.env.SANITY_API_VERSION || '2023-05-03',
  
  // Routing Configuration
  routePath: process.env.CMS_ROUTE_PATH || '/cms/',
  
  // Performance Configuration
  cache: {
    enabled: process.env.ENABLE_CACHE === 'true',
    ttl: parseInt(process.env.CACHE_TTL || '300'),
    staleTime: 300000, // 5 minutes
    strategy: 'stale-while-revalidate'
  },
  
  // SEO Configuration
  seo: {
    siteName: 'My Awesome Site',
    defaultDescription: 'Welcome to our content hub',
    twitterHandle: '@myhandle',
    defaultImage: '/og-image.png'
  }
};

// pages/_app.tsx or app/layout.tsx
import { CmsProvider } from '@ai-growth/nextjs';
import { cmsConfig } from '../lib/cms-config';

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <CmsProvider config={cmsConfig}>
      <Component {...pageProps} />
    </CmsProvider>
  );
}

🎨 Template System

Using Default Templates

The package includes responsive, accessible templates:

import { DefaultTemplate, SimpleDefaultTemplate } from '@ai-growth/nextjs';

// Automatic template selection based on content type
<CmsRouteHandler />

// Explicit template usage
<DefaultTemplate content={content} />
<SimpleDefaultTemplate content={content} />

Custom Templates

// components/MyCustomTemplate.tsx
import { TemplateProps, CmsImage, SEOHead } from '@ai-growth/nextjs';

export function MyCustomTemplate({ content }: TemplateProps) {
  return (
    <>
      <SEOHead content={content} />
      <article className="max-w-4xl mx-auto px-4">
        <header>
          <h1 className="text-4xl font-bold">{content.title}</h1>
          {content.mainImage && (
            <CmsImage
              image={content.mainImage}
              alt={content.title}
              priority
              className="w-full h-64 object-cover rounded-lg"
            />
          )}
        </header>
        <main>
          <ContentBody content={content.content} />
        </main>
      </article>
    </>
  );
}

// Register custom template
import { registerTemplate } from '@ai-growth/nextjs';

registerTemplate('custom', MyCustomTemplate);

Lazy Loading Templates

import { 
  DynamicTemplateLoader,
  LazyDefaultTemplateV2,
  preloadTemplate 
} from '@ai-growth/nextjs';

// Dynamic template loading with preloading
<DynamicTemplateLoader 
  templateName="default-v2"
  preloadOnHover={true}
  content={content}
/>

// Manual preloading
useEffect(() => {
  preloadTemplate('default-v2');
}, []);

🔍 SEO Optimization

Automatic SEO

SEO optimization is automatic with smart defaults:

import { SEOHead, useSEOData } from '@ai-growth/nextjs';

// Automatic SEO for CMS content
<CmsRouteHandler /> // SEO included automatically

// Manual SEO control
function MyPage({ content }) {
  return (
    <>
      <SEOHead 
        content={content}
        siteName="My Site"
        defaultDescription="Amazing content"
      />
      <main>{/* Your content */}</main>
    </>
  );
}

// Access SEO data in components
function MySEOComponent() {
  const seoData = useSEOData();
  return <div>Page title: {seoData.title}</div>;
}

Advanced SEO Configuration

import { processSEO, generateStructuredData } from '@ai-growth/nextjs';

// Custom SEO processing
const seoData = processSEO(content, {
  siteName: 'My Site',
  defaultImage: '/default-og.png',
  twitterHandle: '@mysite',
  customSchema: {
    '@type': 'BlogPosting',
    publisher: {
      '@type': 'Organization',
      name: 'My Company'
    }
  }
});

// Generate structured data
const structuredData = generateStructuredData(content, 'article');

🚀 Performance Features

Multi-Layer Caching

import { 
  CacheProvider, 
  useCmsContentCached,
  CacheManager 
} from '@ai-growth/nextjs';

// Global cache configuration
<CacheProvider 
  config={{
    strategy: 'stale-while-revalidate',
    ttl: 300000, // 5 minutes
    storage: ['memory', 'localStorage', 'indexedDB']
  }}
>
  <App />
</CacheProvider>

// Use cached content hooks
function MyComponent() {
  const { 
    data, 
    loading, 
    error, 
    stale, 
    revalidating,
    cacheHit 
  } = useCmsContentCached('posts', 'my-slug');
  
  return (
    <div>
      {loading && <LoadingSkeleton />}
      {error && <ErrorBoundary error={error} />}
      {data && <ContentDisplay content={data} />}
      {stale && <div>Updating content...</div>}
    </div>
  );
}

// Manual cache operations
const cacheManager = CacheManager.getInstance();
await cacheManager.invalidateByTag('posts');

Image Optimization

import { 
  OptimizedImage, 
  CmsImage, 
  ResponsiveImage,
  HeroImage,
  AvatarImage 
} from '@ai-growth/nextjs';

// Sanity image with optimization
<CmsImage
  image={content.mainImage}
  alt="Hero image"
  width={800}
  height={600}
  priority // Above the fold
  quality={90}
/>

// Responsive images
<ResponsiveImage
  image={content.image}
  aspectRatio="16:9"
  sizes="(max-width: 768px) 100vw, 50vw"
/>

// Specialized image components
<HeroImage image={heroImage} /> {/* Optimized for LCP */}
<AvatarImage image={authorImage} size="lg" /> {/* User avatars */}

Lazy Loading & Code Splitting

import { 
  LazyLoadComponent,
  IntersectionWrapper,
  createLazyComponent,
  useIntersectionObserver 
} from '@ai-growth/nextjs';

// Lazy load below-the-fold content
<LazyLoadComponent
  loader={() => import('./HeavyComponent')}
  fallback={<ContentSkeleton />}
  rootMargin="100px"
/>

// Intersection-based rendering
<IntersectionWrapper placeholder={<div>Loading...</div>}>
  <ExpensiveComponent />
</IntersectionWrapper>

// Custom lazy loading
const LazyComponent = createLazyComponent(
  () => import('./MyComponent'),
  { 
    fallback: <LoadingSkeleton />,
    retryAttempts: 3 
  }
);

// Custom intersection observer
function MyComponent() {
  const [ref, isVisible] = useIntersectionObserver({
    threshold: 0.1,
    rootMargin: '50px'
  });
  
  return (
    <div ref={ref}>
      {isVisible && <ExpensiveContent />}
    </div>
  );
}

🛡️ Error Handling

Error Boundaries

import { 
  ErrorBoundary, 
  CmsErrorBoundary,
  ApiErrorBoundary,
  withErrorBoundary 
} from '@ai-growth/nextjs';

// Wrap components with error boundaries
<ErrorBoundary
  fallback={<ErrorPage />}
  onError={(error, errorInfo) => console.error(error)}
>
  <MyComponent />
</ErrorBoundary>

// CMS-specific error handling
<CmsErrorBoundary>
  <CmsContent />
</CmsErrorBoundary>

// HOC pattern
const SafeComponent = withErrorBoundary(MyComponent, {
  fallback: <div>Something went wrong</div>
});

Error Logging

import { 
  ErrorLogger, 
  logError, 
  logCriticalError 
} from '@ai-growth/nextjs';

// Automatic error logging (configured in CmsProvider)
// Errors are automatically categorized and sent to monitoring

// Manual error logging
try {
  // risky operation
} catch (error) {
  logError(error, {
    category: 'api',
    severity: 'error',
    context: { userId: 'user123' }
  });
}

// Critical errors
logCriticalError(new Error('Payment failed'), {
  context: { orderId: 'order-123' }
});

Fallback Content

import { 
  FallbackContent, 
  ContentFallback,
  useFallbackContent 
} from '@ai-growth/nextjs';

// Provider with fallback content
<FallbackContentProvider>
  <App />
</FallbackContentProvider>

// Component with fallback
<ContentFallback
  type="post"
  fallbackTitle="Content Unavailable"
  fallbackMessage="This content is temporarily unavailable."
  showRetry
  onRetry={() => window.location.reload()}
/>

// Hook for fallback content
function MyComponent() {
  const { getFallbackContent } = useFallbackContent();
  
  const fallback = getFallbackContent('post', 'Unable to load post');
  return <div>{fallback}</div>;
}

🎣 Hooks & Context

Content Hooks

import { 
  useCmsContent,
  useCmsContentList,
  useCmsContentCached,
  useContentPreload 
} from '@ai-growth/nextjs';

// Fetch single content
const { data, loading, error } = useCmsContent('posts', slug);

// Fetch content list
const { data: posts, loading } = useCmsContentList('posts', {
  limit: 10,
  sort: 'publishedAt desc'
});

// Cached content (recommended)
const { data, stale, revalidating } = useCmsContentCached('posts', slug);

// Preload content
const preloadPost = useContentPreload();
preloadPost('posts', 'upcoming-post-slug');

CMS Context

import { useCms, useCmsTheme, useCmsTemplate } from '@ai-growth/nextjs';

function MyComponent() {
  const { config, client, isConnected } = useCms();
  const theme = useCmsTheme();
  const { currentTemplate, setTemplate } = useCmsTemplate();
  
  return (
    <div className={theme.container}>
      Status: {isConnected ? 'Connected' : 'Disconnected'}
      Template: {currentTemplate}
    </div>
  );
}

Cache Context

import { 
  useCacheMetrics, 
  useCacheOperations,
  useCacheDebug 
} from '@ai-growth/nextjs';

function CacheDebug() {
  const { hitRatio, size, responseTime } = useCacheMetrics();
  const { invalidate, clear } = useCacheOperations();
  const debugInfo = useCacheDebug();
  
  return (
    <div>
      <p>Hit Ratio: {hitRatio}%</p>
      <p>Cache Size: {size} entries</p>
      <p>Avg Response: {responseTime}ms</p>
      <button onClick={() => clear()}>Clear Cache</button>
    </div>
  );
}

📱 Loading States

import { 
  LoadingFallback,
  CmsLoadingFallback,
  Skeleton,
  ContentSkeleton,
  useLoading 
} from '@ai-growth/nextjs';

// Pre-built loading components
<LoadingFallback message="Loading content..." />
<CmsLoadingFallback contentType="article" />

// Skeleton components
<Skeleton width={200} height={20} />
<ContentSkeleton />

// Loading state management
function MyComponent() {
  const { isLoading, setLoading } = useLoading();
  
  const handleSubmit = async () => {
    setLoading(true);
    try {
      await submitData();
    } finally {
      setLoading(false);
    }
  };
  
  return (
    <button onClick={handleSubmit} disabled={isLoading}>
      {isLoading ? 'Submitting...' : 'Submit'}
    </button>
  );
}

🔧 Configuration Options

Complete Configuration

interface CmsConfig {
  // Sanity Configuration
  projectId: string;
  dataset: string;
  apiToken?: string;
  apiVersion?: string;
  useCdn?: boolean;
  
  // Routing Configuration
  routePath?: string;
  baseUrl?: string;
  
  // Performance Configuration
  cache?: {
    enabled?: boolean;
    ttl?: number;
    staleTime?: number;
    strategy?: 'cache-first' | 'network-first' | 'stale-while-revalidate';
    storage?: ('memory' | 'localStorage' | 'sessionStorage' | 'indexedDB')[];
  };
  
  // SEO Configuration
  seo?: {
    siteName?: string;
    defaultDescription?: string;
    defaultImage?: string;
    twitterHandle?: string;
    facebookAppId?: string;
  };
  
  // Error Handling Configuration
  errorHandling?: {
    enableLogging?: boolean;
    enableRetry?: boolean;
    maxRetries?: number;
    retryDelay?: number;
  };
  
  // Image Configuration
  images?: {
    quality?: number;
    formats?: ('webp' | 'avif' | 'jpeg' | 'png')[];
    breakpoints?: { [key: string]: number };
  };
  
  // Development Configuration
  debug?: boolean;
  logLevel?: 'error' | 'warn' | 'info' | 'debug';
}

Environment Variables

| Variable | Required | Default | Description | |----------|----------|---------|-------------| | SANITY_PROJECT_ID | ✅ | - | Sanity project ID | | SANITY_DATASET | ✅ | - | Sanity dataset name | | SANITY_API_TOKEN | ❌ | - | API token for private content (optional for public data) | | SANITY_API_VERSION | ❌ | 2023-05-03 | Sanity API version | | CMS_ROUTE_PATH | ❌ | /cms/ | URL pattern for CMS pages | | ENABLE_CACHE | ❌ | true | Enable caching system | | CACHE_TTL | ❌ | 300 | Cache TTL in seconds | | ENABLE_DEBUG | ❌ | false | Enable debug mode | | LOG_LEVEL | ❌ | error | Logging level |

Next.js Public Variables (Client-side Access)

For client-side access, use the NEXT_PUBLIC_ prefixed versions:

| Variable | Description | |----------|-------------| | NEXT_PUBLIC_SANITY_PROJECT_ID | Client-accessible project ID | | NEXT_PUBLIC_SANITY_DATASET | Client-accessible dataset name | | NEXT_PUBLIC_SANITY_API_VERSION | Client-accessible API version | | NEXT_PUBLIC_CMS_ROUTE_PATH | Client-accessible route path |

Security Note: Never use NEXT_PUBLIC_SANITY_API_TOKEN as API tokens should never be exposed to the client.

🎯 API Reference

Components

Core Components

  • CmsProvider - Main provider component
  • CmsRouteHandler - Route handling component
  • DefaultTemplate - Default content template
  • SimpleDefaultTemplate - Minimal content template

SEO Components

  • SEOHead - Complete SEO head component
  • SafeSEOHead - Error-resilient SEO component
  • BasicSEO - Minimal SEO component
  • StructuredDataOnly - JSON-LD only component

Image Components

  • OptimizedImage - Base optimized image
  • CmsImage - Sanity-specific image
  • ResponsiveImage - Responsive image component
  • HeroImage - Above-the-fold optimized
  • AvatarImage - User avatar component

Error Components

  • ErrorBoundary - Base error boundary
  • CmsErrorBoundary - CMS-specific errors
  • ApiErrorBoundary - API error handling
  • NotFoundPage - 404 error page
  • ServerErrorPage - 500 error page

Loading Components

  • LoadingFallback - Generic loading component
  • CmsLoadingFallback - CMS loading states
  • Skeleton - Skeleton placeholder
  • ContentSkeleton - Content-specific skeleton

Lazy Loading Components

  • LazyLoadComponent - Intersection-based lazy loading
  • DynamicTemplateLoader - Dynamic template loading
  • IntersectionWrapper - Viewport-based rendering

Hooks

Content Hooks

  • useCmsContent(type, slug) - Fetch single content
  • useCmsContentList(type, options) - Fetch content list
  • useCmsContentCached(type, slug) - Cached content fetching
  • useContentPreload() - Content preloading

Context Hooks

  • useCms() - CMS context access
  • useCmsTheme() - Theme context
  • useCmsTemplate() - Template context
  • useCacheMetrics() - Cache performance metrics
  • useCacheOperations() - Cache operations
  • useSEOData() - SEO data access

Utility Hooks

  • useLoading() - Loading state management
  • useIntersectionObserver() - Intersection observer
  • useDynamicImport() - Dynamic component loading
  • useHoverPreload() - Hover-based preloading

Utilities

Cache Utilities

  • CacheManager - Advanced cache management
  • createCacheManager(config) - Cache factory
  • invalidateCache(pattern) - Cache invalidation

SEO Utilities

  • processSEO(content, config) - SEO data processing
  • generateStructuredData(content, type) - JSON-LD generation
  • sanitizeSEO(data) - SEO data sanitization

Image Utilities

  • sanityImageLoader(config) - Sanity image loader
  • processImageForNextJS(image, options) - Image processing
  • calculateOptimalDimensions(image, constraints) - Size calculation

Error Utilities

  • ErrorLogger - Enterprise error logging
  • logError(error, context) - Error logging
  • logCriticalError(error, context) - Critical error logging

Lazy Loading Utilities

  • createLazyComponent(loader, options) - Lazy component factory
  • preloadComponents(components) - Batch preloading
  • preloadByPriority(components, priority) - Priority preloading

Types

All TypeScript definitions are included. Key types:

// Core Types
interface CmsConfig { /* ... */ }
interface CmsContent { /* ... */ }
interface TemplateProps { /* ... */ }

// SEO Types
interface SEOData { /* ... */ }
interface StructuredData { /* ... */ }

// Cache Types
interface CacheConfig { /* ... */ }
interface CacheEntry { /* ... */ }
interface CacheMetrics { /* ... */ }

// Error Types
interface ErrorContext { /* ... */ }
interface ErrorLogEntry { /* ... */ }

// Image Types
interface ImageProcessingOptions { /* ... */ }
interface ResponsiveBreakpoint { /* ... */ }

🚀 Performance Optimization

Bundle Size

  • Core: ~15KB gzipped
  • With all features: ~45KB gzipped
  • Tree-shakeable: Import only what you need

Performance Features

  • Code Splitting: Template-level splitting
  • Lazy Loading: Component and route-based
  • Image Optimization: WebP/AVIF, responsive sizing
  • Caching: Multi-layer with SWR patterns
  • Preloading: Smart predictive loading
  • Error Handling: Non-blocking error recovery
  • SEO Optimization: Complete meta tag management

Lighthouse Score Improvements

Typical improvements with this package:

  • Performance: +15-25 points
  • Accessibility: +10-15 points
  • Best Practices: +5-10 points
  • SEO: +20-30 points

🏗️ Architecture

System Overview

┌─────────────────────────────────────────┐
│                CmsProvider              │
├─────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────────┐   │
│  │ Cache Layer │  │ Error Handling  │   │
│  └─────────────┘  └─────────────────┘   │
├─────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────────┐   │
│  │ SEO System  │  │ Image Optimizer │   │
│  └─────────────┘  └─────────────────┘   │
├─────────────────────────────────────────┤
│           Template Engine               │
├─────────────────────────────────────────┤
│           Sanity Client                 │
└─────────────────────────────────────────┘

Key Design Principles

  • Progressive Enhancement: Works without JavaScript
  • Performance First: Optimized for Core Web Vitals
  • Developer Experience: Rich TypeScript support
  • Accessibility: WCAG 2.1 AA compliant
  • SEO Optimized: Comprehensive meta tag management
  • Error Resilient: Graceful degradation patterns

🧪 Testing

Running Tests

# Run all tests
npm test

# Watch mode
npm run test:watch

# Coverage report
npm run test:coverage

# CI mode
npm run test:ci

Test Coverage

Current test coverage: >90% across all modules

  • Components: 95% coverage
  • Hooks: 92% coverage
  • Utilities: 94% coverage
  • Error Handling: 97% coverage

🤝 Contributing

We welcome contributions! Please see our Contributing Guidelines for details.

Development Setup

# Clone repository
git clone https://github.com/ai-growth/nextjs.git
cd nextjs

# Install dependencies
npm install

# Start development
npm run dev

# Run tests
npm test

# Build package
npm run build

Code Quality Standards

  • TypeScript: Strict mode enabled
  • ESLint: Airbnb configuration + custom rules
  • Prettier: Consistent code formatting
  • Husky: Pre-commit hooks
  • Jest: Comprehensive testing
  • Conventional Commits: Standardized commit messages

📚 Documentation

🔧 Requirements

  • Node.js: 16.0.0 or higher
  • Next.js: 12.0.0 or higher (13+ recommended)
  • React: 17.0.0 or higher (18+ recommended)
  • TypeScript: 4.5+ (optional but recommended)
  • Sanity CMS: Active project with content

🌐 Browser Support

Modern browsers supporting ES2020:

  • Chrome: 80+
  • Firefox: 72+
  • Safari: 13.1+
  • Edge: 80+

📄 License

MIT © AI Growth Team

🙏 Acknowledgments

Built with these amazing technologies:

📞 Support & Community


Made with ❤️ by the AI Growth Team

⭐ Star us on GitHub📦 View on npm

Environment Variable Configuration

This library supports both regular environment variables and Next.js public environment variables for better flexibility:

Variable Priority

When configuring the Sanity connection, the library checks for variables in the following order:

  1. Next.js public variables (NEXT_PUBLIC_*) if available
  2. Regular variables as fallback

Supported Variables

| Purpose | Next.js Public Variable | Regular Variable | Required? | |------------------|--------------------------------|-------------------------|-----------------------| | Project ID | NEXT_PUBLIC_SANITY_PROJECT_ID| SANITY_PROJECT_ID | Yes | | Dataset | NEXT_PUBLIC_SANITY_DATASET | SANITY_DATASET | Yes | | API Version | NEXT_PUBLIC_SANITY_API_VERSION| SANITY_API_VERSION | No (default: 2023-05-03) | | CMS Route Path | NEXT_PUBLIC_CMS_ROUTE_PATH | CMS_ROUTE_PATH | No (default: /cms/) | | API Token | - | SANITY_API_TOKEN | No* |

*API Token Note: The API token is only required for:

  • Writing data to Sanity
  • Accessing draft content
  • Bypassing the CDN for real-time content

For read-only access to published content, you can omit the API token entirely. The library will automatically use the Sanity CDN for better performance when no token is provided.

Usage in Client vs Server Components

  • Server Components: Can access all variables
  • Client Components: Can only access NEXT_PUBLIC_* variables or variables exposed through the client-safe configuration helpers

Example Configuration

# .env file
# Public variables (accessible in browser)
NEXT_PUBLIC_SANITY_PROJECT_ID=your-project-id
NEXT_PUBLIC_SANITY_DATASET=production

# Server-only variables (not exposed to browser)
SANITY_API_TOKEN=your-api-token  # Optional, for write access or draft content