Introduction To Sanity CMS
Sanity is a headless Content Management System (CMS) that provides a flexible, API-driven approach to content management. In the Charles Schwab NextJS Web Monorepo, Sanity serves as the primary content backend for managing structured content across multiple applications.
Overview
Our Sanity implementation consists of two main components:
- Sanity Studio (
apps/sanity-studio) - The content editing interface - Sanity Next (
apps/sanity-next) - Demo frontend application for content preview
Sanity Studio Application
Purpose and Function
Application: apps/sanity-studio
Port: 3333
Purpose: Content authoring and management interface
Version: 1.0.9
Sanity Studio is a customizable content management interface built on top of Next.js 15.3.2 that allows content creators and editors to manage structured content.
Key Features
| Feature | Description | Implementation |
|---|---|---|
| Multi-language Support | Content internationalization for Chinese, Spanish, and English | @sanity/document-internationalization |
| SAML Authentication | Enterprise authentication via Schwab SSO | Custom auth store configuration |
| Asset Management | Integration with Bynder DAM and Unsplash | Plugins: bynder-input, unsplash-asset-source |
| Content Validation | Schema-based content validation | Zod integration with custom validation rules |
| Preview Mode | Live preview integration with frontend apps | Presentation tool with draft mode |
| Taxonomy Management | Structured content categorization | sanity-plugin-taxonomy-manager |
| AI Assistant | Content translation and assistance | @sanity/assist plugin |
| Table Support | Rich table editing capabilities | @sanity/table plugin |
Technical Architecture
Core Dependencies
{
"sanity": "^3.81.0",
"next": "15.5.7",
"next-sanity": "^9.9.6",
"@sanity/ui": "^2.15.10",
"@sanity/vision": "^3.81.0"
}
Project Configuration
- Project ID:
fvuvea00 - Dataset:
production - Authentication: SAML with Schwab enterprise login
Supported Languages
| Language Code | Language Name |
|---|---|
zh-CN | Chinese (China) |
zh-TW | Chinese (Taiwan-Traditional) |
es-US | Spanish (US) |
en-US | English (US) |
Content Schema Architecture
Document Types
| Document Type | Purpose | Key Fields |
|---|---|---|
story | Articles, blog posts, content pages | title, slug, summary, body, language |
landingPage | Marketing and product landing pages | title, slug, summary, components |
cardDeck | Card-based content layouts | cardType, cards, styling |
dataTable | Structured tabular data | headers, rows, styling |
taxonomyTerm | Content categorization | name, parent, attributes |
taxonomyAttribute | Taxonomy metadata | name, type, values |
querySet | Dynamic content queries | query, parameters, caching |
dynamicCta | Call-to-action components | text, link, styling |
bynderBlock | Digital asset management | asset references, metadata |
Object Types
| Object Type | Purpose | Usage |
|---|---|---|
button | Interactive button components | CTAs, navigation |
marquee | Scrolling text displays | Announcements, alerts |
seoData | SEO metadata | Page optimization |
seoItem | Individual SEO elements | Meta tags, structured data |
stylingVariation | Visual style options | Theme variations |
taxonomyItem | Taxonomy references | Content categorization |
Workspace Configuration
Sanity Studio supports multiple workspaces for different content domains:
Default Workspace
- Name:
default - Title: "Charles Schwab"
- Path:
/default - Purpose: Primary content management for public-facing content
Charitable Workspace
- Name:
charitable - Title: "Charitable"
- Path:
/charitable - Purpose: Content management for Charles Schwab Charitable programs
Sanity Next Demo Application
Purpose and Function
Application: apps/sanity-next
Purpose: Demo Next.js application for Sanity content preview
Preview URL: https://schwab-sanity-next.vercel.app
Status: Proof-of-concept application
Sanity Next is a demonstration frontend application that showcases how to integrate Sanity CMS with Next.js for content delivery and preview capabilities. This app serves as a reference implementation for connecting Sanity to production applications.
Key Features
| Feature | Description | Purpose |
|---|---|---|
| Draft Mode Preview | Live preview of unpublished content | Enables content editors to preview changes before publishing |
| Content Routing | Dynamic routing for stories and landing pages | Demonstrates content-driven page generation |
| API Integration | Content delivery via Sanity API | Shows proper API connection patterns |
| Multi-language Support | Preview content in multiple languages | Tests internationalization capabilities |
Technical Integration
Preview Configuration
The Sanity Studio is configured to use sanity-next as its preview environment:
{
previewUrl: {
origin: "https://schwab-sanity-next.vercel.app",
draftMode: {
enable: "/api/draft"
}
}
}
Content Type Routing
| Content Type | Route Pattern | Example |
|---|---|---|
story | /{language}/story/{slug} | /en-US/story/market-insights |
landingPage | /{language}/{slug} | /en-US/investing |
Development Workflow
Local Development
# Start both Sanity Studio and Demo App
pnpm dev-sanity
# This runs both:
# - Sanity Studio on port 3333
# - Sanity Next demo on its configured port
Build Process
# Build both applications
pnpm build-sanity
# Builds:
# - Sanity Studio
# - Sanity Next demo app
Future Plans
The sanity-next application is a proof-of-concept and will eventually be deprecated once Sanity content delivery is fully integrated into production applications like www.schwab.com and client.schwab.com.
Plugin Ecosystem
Core Plugins
| Plugin | Version | Purpose |
|---|---|---|
@sanity/assist | ^3.2.2 | AI-powered content assistance and translation |
@sanity/code-input | ^5.1.2 | Code syntax highlighting in content |
@sanity/document-internationalization | ^3.3.1 | Multi-language content management |
@sanity/table | ^1.1.3 | Rich table editing capabilities |
@sanity/vision | ^3.81.0 | GROQ query development tool |
Integration Plugins
| Plugin | Purpose | Configuration |
|---|---|---|
sanity-plugin-bynder-input | Digital Asset Management | Bynder portal integration |
sanity-plugin-asset-source-unsplash | Stock photography | Unsplash image library |
sanity-plugin-taxonomy-manager | Content categorization | Schwab vocabulary management |
sanity-plugin-studio-smartling | Translation services | Professional translation workflow |
Development Workflow
Local Development
# Start Sanity Studio
pnpm dev-sanity
# Runs on port 3333
# URL: http://localhost:3333
Schema Management
# Generate TypeScript types from schemas
pnpm typegen
# Extracts schema and generates type definitions
Content Structure
Integration with Frontend Applications
Content Delivery Pattern
API Integration
Frontend applications integrate with Sanity using:
- next-sanity: Official Next.js integration package
- GROQ Queries: Content querying language
- Preview Mode: Draft content preview (demonstrated in sanity-next)
- Image CDN: Optimized image delivery
Preview Integration Example
The sanity-next demo application demonstrates the preview integration pattern:
// Example preview API route pattern
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const slug = searchParams.get('slug');
const type = searchParams.get('type');
// Enable draft mode for preview
draftMode().enable();
// Redirect to the preview page
redirect(`/${type}/${slug}`);
}
Content Types in Production
| Content Type | Usage | Frontend Integration |
|---|---|---|
| Stories | Blog posts, articles | Dynamic routing, SEO optimization |
| Landing Pages | Marketing pages | Component-based rendering |
| Card Decks | Product showcases | Grid layouts, interactive cards |
| Data Tables | Financial data | Responsive tables, data visualization |
| Taxonomy | Content categorization | Filtering, navigation |
Security and Authentication
Access Control
- SAML Integration: Enterprise SSO with Schwab credentials
- Role-based Permissions: Administrator and editor roles
- Workspace Isolation: Content segregation by domain
- API Security: Token-based authentication for content delivery
Content Security
Development Guidelines
Schema Development
- Type Safety: Always define proper TypeScript types
- Validation Rules: Implement comprehensive content validation
- Internationalization: Support multi-language content from the start
- SEO Optimization: Include SEO fields in all public content types
Content Management Best Practices
- Content Structure: Use consistent field naming and organization
- Asset Management: Leverage Bynder integration for brand compliance
- Preview Testing: Always test content in preview mode before publishing
- Performance: Optimize queries and content structure for fast delivery
Testing Strategy
- Schema Validation: Jest tests for schema integrity
- Content Queries: GROQ query testing
- Integration Tests: Frontend content rendering tests
- Accessibility: Content accessibility validation
Monitoring and Maintenance
Performance Monitoring
- API Response Times: Content delivery performance
- Studio Performance: Editor experience optimization
- Build Times: Schema compilation and type generation
- Cache Efficiency: Content delivery caching strategies
Maintenance Tasks
| Task | Frequency | Purpose |
|---|---|---|
| Schema Updates | As needed | New content types and fields |
| Plugin Updates | Monthly | Security and feature updates |
| Content Cleanup | Quarterly | Remove unused content and assets |
| Performance Review | Monthly | Optimize queries and delivery |
This Sanity CMS implementation provides a robust, scalable content management foundation for Charles Schwab's digital properties, enabling efficient content creation, management, and delivery across multiple applications and languages.