
Nuxt Studio
- 73 installs
- 202 repo stars
- Updated August 4, 2026
- secondsky/claude-skills
Helps with ai & agent building tasks during AI-assisted development.
About
nuxt studio is a Claude Code skill for ai & agent building. It helps developers move faster with AI-assisted coding.
- nuxt studio
- AI & Agent Building
- AI-coding skill
Nuxt Studio by the numbers
- 73 all-time installs (skills.sh)
- Ranked #5,587 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/secondsky/claude-skills --skill nuxt-studioAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 73 |
|---|---|
| repo stars | ★ 202 |
| Last updated | August 4, 2026 |
| Repository | secondsky/claude-skills ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Nuxt Studio Setup and Deployment
Overview
Nuxt Studio is a free, open-source visual content editor for Nuxt Content websites that enables content editing directly in production. It provides multiple editor types (Monaco code editor, TipTap visual WYSIWYG editor, Form-based editor), OAuth authentication (GitHub/GitLab/Google), and Git-based content management with commit integration.
Primary use case: Add visual CMS capabilities to existing Nuxt Content websites, typically deployed to a subdomain like studio.domain.com or cms.domain.com.
When to Use This Skill
Use this skill when users need to:
- Set up Nuxt Studio for the first time on a Nuxt Content website
- Configure OAuth authentication for Studio access
- Deploy Studio to Cloudflare Pages or Workers with custom subdomain
- Troubleshoot Studio authentication, build, or deployment issues
- Configure editor types or customize Studio behavior
- Integrate Studio with existing Nuxt v3/v4 applications
Prerequisites Check
Before proceeding with Studio setup, verify these requirements:
1. Nuxt Version: ≥3.x (Studio requires Nuxt 3) 2. @nuxt/content Module: ≥2.x (required dependency) 3. Node.js: ≥18.x recommended 4. Cloudflare Account: Required for Cloudflare deployment (optional for other platforms)
Check Nuxt Content installation:
# Verify @nuxt/content is installed
grep "@nuxt/content" package.json
# Check nuxt.config.ts for content module
grep "modules.*content" nuxt.config.tsIf Nuxt Content is not installed, install it first:
npx nuxi module add contentInstallation
1. Install Nuxt Studio Module
Install the latest beta version (v1.0.0-beta.3 as of December 2025):
npx nuxi module add nuxt-studio@betaThis adds @nuxt/studio to devDependencies and configures the module in nuxt.config.ts.
2. Verify Module Configuration
Check that nuxt.config.ts includes the Studio module:
// nuxt.config.ts
export default defineNuxtConfig({
modules: [
'@nuxt/content',
'@nuxt/studio' // Added automatically
]
})3. Start Development Mode
Run the development server to test Studio locally:
npm run dev
# or
bun devAccess Studio at http://localhost:3000/_studio (development mode).
OAuth Authentication Setup
Studio requires OAuth authentication for production deployments. Choose one provider:
Supported Providers
- GitHub OAuth: Best for public repositories and GitHub-hosted projects
- GitLab OAuth: Ideal for self-hosted GitLab instances
- Google OAuth: Universal option for any setup
Quick OAuth Configuration
For detailed OAuth setup instructions for each provider, load `references/oauth-providers.md`.
Environment variables pattern (all providers):
# GitHub
NUXT_OAUTH_GITHUB_CLIENT_ID=your_client_id
NUXT_OAUTH_GITHUB_CLIENT_SECRET=your_client_secret
# GitLab
NUXT_OAUTH_GITLAB_CLIENT_ID=your_client_id
NUXT_OAUTH_GITLAB_CLIENT_SECRET=your_client_secret
# Google
NUXT_OAUTH_GOOGLE_CLIENT_ID=your_client_id
NUXT_OAUTH_GOOGLE_CLIENT_SECRET=your_client_secretCallback URL pattern:
https://studio.yourdomain.com/api/auth/callback/[provider]Replace [provider] with: github, gitlab, or google.
For complete OAuth app creation steps, consult `references/oauth-providers.md`.
Cloudflare Deployment
Studio works excellently on Cloudflare Pages and Workers. Use the Cloudflare deployment for:
- Serverless edge deployment
- Custom subdomain routing (e.g.,
studio.domain.com) - Environment variable management via dashboard
- Automatic builds from Git
Cloudflare Setup Overview
1. Configure Nitro preset for Cloudflare in nuxt.config.ts 2. Create or update `wrangler.toml` for Workers deployment (optional) 3. Set environment variables on Cloudflare dashboard 4. Configure custom domain and subdomain routing 5. Deploy via Cloudflare Pages or Workers
For complete Cloudflare deployment instructions, load `references/cloudflare-deployment.md`.
Quick Cloudflare Configuration
Set the Cloudflare Pages preset:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/content', '@nuxt/studio'],
nitro: {
preset: 'cloudflare-pages'
}
})For Workers deployment with custom subdomain routing, see `references/cloudflare-deployment.md`.
Editor Types
Studio provides three editor types that can be configured per content type:
1. Monaco Editor: Code editor for markdown, YAML, JSON 2. TipTap Editor: Visual WYSIWYG editor with MDC component support (default) 3. Form Editor: Schema-driven form for YAML/JSON files
Configure Default Editor
// nuxt.config.ts
export default defineNuxtConfig({
studio: {
editor: {
default: 'tiptap' // or 'monaco' or 'form'
}
}
})For detailed editor configuration options, load `references/editor-configuration.md`.
Subdomain Configuration
Deploy Studio to a subdomain for production use:
Common patterns:
studio.yourdomain.comcms.yourdomain.comedit.yourdomain.comadmin.yourdomain.com
DNS Setup
1. Add a CNAME record in your DNS provider 2. Point subdomain to Cloudflare Pages deployment 3. Configure custom domain in Cloudflare Pages settings
For complete subdomain setup with Cloudflare, load `references/subdomain-setup.md`.
Top 5 Common Errors
1. OAuth Redirect URI Mismatch
Error: Authentication loop or "redirect_uri_mismatch" error
Cause: OAuth app callback URL doesn't match actual deployment URL
Solution:
Ensure OAuth app callback URL is:
https://studio.yourdomain.com/api/auth/callback/[provider]
Not:
https://yourdomain.com/api/auth/callback/[provider]2. Module Not Found: @nuxt/studio
Error: Cannot find module '@nuxt/studio'
Cause: Studio module not installed or installed incorrectly
Solution:
npx nuxi module add nuxt-studio@beta
# or
npm install -D @nuxt/studio3. Cloudflare Pages Build Failure
Error: Build fails with "Incompatible module" or runtime errors
Cause: Nitro preset not configured for Cloudflare
Solution:
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'cloudflare-pages'
}
})4. Authentication Loop After Login
Error: Redirects to login repeatedly after successful OAuth
Cause: Session cookies not persisting due to domain mismatch
Solution:
- Verify
NUXT_PUBLIC_STUDIO_URLenvironment variable matches deployment URL - Check cookie settings in browser (must allow third-party cookies for OAuth)
- Ensure deployment URL uses HTTPS (not HTTP)
5. Subdomain Routing Not Working
Error: Studio loads on main domain instead of subdomain
Cause: DNS/wrangler configuration incorrect
Solution:
- Verify CNAME record points to Cloudflare Pages
- Check custom domain configuration in Cloudflare dashboard
- For Workers: verify
wrangler.tomlroutes configuration
For complete error catalog and solutions, load `references/troubleshooting.md`.
Working with Templates
The skill includes working configuration templates:
- `templates/nuxt.config.ts`: Complete Studio module configuration
- `templates/wrangler.toml`: Cloudflare Workers deployment config
- `templates/studio-auth-github.ts`: GitHub OAuth implementation
- `templates/studio-auth-gitlab.ts`: GitLab OAuth implementation
- `templates/studio-auth-google.ts`: Google OAuth implementation
Use these as starting points for your Studio setup.
Development Workflow
Local Development
1. Install Studio module: npx nuxi module add nuxt-studio@beta 2. Start dev server: npm run dev 3. Access Studio: http://localhost:3000/_studio 4. Edit content visually 5. Commit changes from Studio UI
Production Deployment
1. Configure OAuth provider (GitHub/GitLab/Google) 2. Set environment variables on deployment platform 3. Configure Nitro preset for target platform 4. Deploy to Cloudflare Pages/Workers or other platform 5. Set up custom subdomain 6. Test authentication and content editing
Validation Checklist
Before deploying Studio to production:
- [ ] Nuxt Content installed and configured (≥v2.x)
- [ ] Nuxt version ≥3.x
- [ ] @nuxt/studio module installed
- [ ] OAuth provider configured with valid credentials
- [ ] Environment variables set correctly
- [ ] Nitro preset configured for deployment platform
- [ ] Custom subdomain DNS configured
- [ ] Callback URLs match deployment URL
- [ ] Studio accessible at subdomain URL
- [ ] Authentication working correctly
- [ ] Content editing and commit functionality tested
When to Load References
Load reference files when working on specific aspects:
- OAuth setup: Load
references/oauth-providers.mdfor detailed GitHub/GitLab/Google OAuth app creation - Cloudflare deployment: Load
references/cloudflare-deployment.mdfor complete Cloudflare Pages/Workers setup with wrangler, custom domains, and environment variables - Editor configuration: Load
references/editor-configuration.mdfor Monaco/TipTap/Form editor customization - Subdomain setup: Load
references/subdomain-setup.mdfor DNS and routing configuration - Troubleshooting: Load
references/troubleshooting.mdfor comprehensive error solutions and debugging
Utility Scripts
Use the included scripts for common operations:
- `scripts/check-prerequisites.sh`: Verify Nuxt Content and version requirements
- `scripts/validate-config.sh`: Check nuxt.config.ts Studio configuration
- `scripts/test-oauth.sh`: Test OAuth environment variables setup
Run scripts with:
bash $CLAUDE_PLUGIN_ROOT/skills/nuxt-studio/scripts/script-name.shIntegration with Other Skills
This skill works well with:
- nuxt-content: Prerequisites for Studio (content module required)
- nuxt-v4: Core Nuxt framework knowledge for configuration
- cloudflare-worker-base: Cloudflare deployment fundamentals
- better-auth: Alternative authentication patterns if custom auth needed
Additional Resources
- Nuxt Studio Repository: https://github.com/nuxt-content/studio
- Nuxt Content Documentation: https://content.nuxt.com
- Cloudflare Pages: https://pages.cloudflare.com
- OAuth Documentation: GitHub/GitLab/Google developer docs
Version Information
- Nuxt Studio: v1.0.0-beta.3 (latest as of December 2025)
- Nuxt: ≥3.x required
- @nuxt/content: ≥2.x required
- Node.js: ≥18.x recommended
For the latest version information, check: https://github.com/nuxt-content/studio/releases
---
Next steps: After Studio is configured, test the deployment thoroughly, ensure OAuth authentication works correctly, and verify that content editing and Git commits function as expected.
Cloudflare Deployment for Nuxt Studio
Complete guide for deploying Nuxt Studio to Cloudflare Pages and Workers with custom subdomain routing.
Overview
Cloudflare provides two deployment options for Nuxt Studio:
1. Cloudflare Pages: Git-integrated automatic deployments (recommended) 2. Cloudflare Workers: Direct deployment with wrangler CLI
Both support:
- Custom subdomain routing (
studio.domain.com) - Environment variables for OAuth secrets
- Edge deployment for global performance
- Automatic HTTPS/SSL
Prerequisites
Before deploying to Cloudflare:
- [ ] Cloudflare account created
- [ ] Domain added to Cloudflare (for custom subdomain)
- [ ] Nuxt Studio configured locally
- [ ] OAuth provider credentials ready
- [ ]
wranglerCLI installed (for Workers deployment)
Option 1: Cloudflare Pages (Recommended)
Step 1: Configure Nitro Preset
Update nuxt.config.ts:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/content', '@nuxt/studio'],
nitro: {
preset: 'cloudflare-pages'
}
})Step 2: Push Code to Git Repository
Studio on Cloudflare Pages requires Git integration:
# Initialize git (if not already)
git init
git add .
git commit -m "Configure Studio for Cloudflare Pages"
# Push to GitHub/GitLab
git remote add origin https://github.com/username/repo.git
git push -u origin mainStep 3: Create Cloudflare Pages Project
1. Go to Cloudflare Dashboard → Workers & Pages 2. Click "Create application" → "Pages" → "Connect to Git" 3. Authenticate with GitHub or GitLab 4. Select your repository 5. Configure build settings:
- Framework preset: Nuxt.js
- Build command:
npm run build(orbun run build) - Build output directory:
.output/public - Root directory:
/(or your app directory)
6. Click "Save and Deploy"
Step 4: Configure Environment Variables
During initial setup or after creation:
1. Go to Workers & Pages → Select project → Settings → Environment variables 2. Add OAuth credentials:
NUXT_OAUTH_GITHUB_CLIENT_ID=your_client_idNUXT_OAUTH_GITHUB_CLIENT_SECRET=your_client_secret
3. For production AND preview environments:
- Click "Add variable" for each
- Select both Production and Preview checkboxes
4. Click "Save"
Step 5: Configure Custom Subdomain
Add Custom Domain
1. In Pages project, go to Custom domains 2. Click "Set up a custom domain" 3. Enter subdomain: studio.yourdomain.com 4. Click "Continue" 5. Cloudflare automatically creates DNS records (if domain is on Cloudflare)
Manual DNS Configuration
If domain is not on Cloudflare DNS:
1. Add CNAME record in your DNS provider:
- Name:
studio - Target:
your-project.pages.dev - TTL: Auto or 3600
2. Wait for DNS propagation (up to 48 hours, usually faster) 3. Verify in Cloudflare dashboard
Step 6: Update OAuth Callback URLs
Update OAuth app callback URLs to match subdomain:
https://studio.yourdomain.com/api/auth/callback/githubStep 7: Deploy and Test
1. Push changes to trigger deployment:
git add .
git commit -m "Add custom subdomain config"
git push2. Monitor deployment in Cloudflare dashboard 3. Visit https://studio.yourdomain.com 4. Test OAuth authentication 5. Verify content editing works
---
Option 2: Cloudflare Workers
Step 1: Install Wrangler CLI
npm install -g wrangler
# or
bun add -g wranglerStep 2: Authenticate Wrangler
wrangler loginThis opens browser for Cloudflare authentication.
Step 3: Configure Nitro Preset
Update nuxt.config.ts:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/content', '@nuxt/studio'],
nitro: {
preset: 'cloudflare' // Use 'cloudflare' for Workers
}
})Step 4: Create wrangler.toml
Create wrangler.toml in project root:
name = "studio-cms"
main = "./.output/server/index.mjs"
compatibility_date = "2025-12-25"
[site]
bucket = "./.output/public"
# Custom subdomain routing
routes = [
{ pattern = "studio.yourdomain.com/*", zone_name = "yourdomain.com" }
]
# Environment variables (reference only, set via dashboard)
[vars]
# NUXT_OAUTH_GITHUB_CLIENT_ID will be set via dashboardStep 5: Build for Workers
npm run build
# or
bun run buildThis creates .output/ directory with Worker-compatible build.
Step 6: Deploy to Workers
wrangler deployOr with custom name:
wrangler deploy --name studio-cmsStep 7: Configure Custom Routes
For subdomain routing:
1. Go to Cloudflare Dashboard → Workers & Pages → Your Worker 2. Click Routes → Add route 3. Configure:
- Route:
studio.yourdomain.com/* - Zone:
yourdomain.com - Worker:
studio-cms
4. Click "Save"
Step 8: Set Environment Variables
Workers environment variables:
# Set via wrangler CLI
wrangler secret put NUXT_OAUTH_GITHUB_CLIENT_ID
# Enter value when prompted
wrangler secret put NUXT_OAUTH_GITHUB_CLIENT_SECRET
# Enter secret when promptedOr via dashboard: 1. Workers & Pages → Select worker → Settings → Variables 2. Add secrets as encrypted environment variables
Step 9: Test Deployment
1. Visit https://studio.yourdomain.com 2. Verify routing works correctly 3. Test OAuth authentication 4. Check content editing functionality
---
Subdomain Routing Configuration
Cloudflare Pages Subdomain
Pages automatically handles subdomains via custom domains feature:
1. Custom domains → Set up a custom domain 2. Enter: studio.yourdomain.com 3. Cloudflare creates CNAME record automatically
DNS Record Created:
studio.yourdomain.com CNAME your-project.pages.devCloudflare Workers Subdomain
Workers require route configuration:
Option A: wrangler.toml routes:
routes = [
{ pattern = "studio.yourdomain.com/*", zone_name = "yourdomain.com" }
]Option B: Dashboard route configuration: 1. Workers & Pages → Worker → Routes → Add route 2. Route: studio.yourdomain.com/* 3. Zone: yourdomain.com
---
Environment Variables Best Practices
Cloudflare Pages Variables
Set variables in dashboard: 1. Workers & Pages → Project → Settings → Environment variables 2. Add for both Production and Preview
Production variables:
NUXT_OAUTH_GITHUB_CLIENT_ID = prod_client_id
NUXT_OAUTH_GITHUB_CLIENT_SECRET = prod_secretPreview variables (different OAuth app for preview):
NUXT_OAUTH_GITHUB_CLIENT_ID = preview_client_id
NUXT_OAUTH_GITHUB_CLIENT_SECRET = preview_secretCloudflare Workers Secrets
Use wrangler secret for sensitive data:
wrangler secret put NUXT_OAUTH_GITHUB_CLIENT_SECRETThis encrypts the value and stores securely.
For non-sensitive variables, use wrangler.toml:
[vars]
NUXT_PUBLIC_STUDIO_URL = "https://studio.yourdomain.com"---
Build Configuration
Cloudflare Pages Build Settings
Optimal build configuration:
- Build command:
npm run buildorbun run build - Build output directory:
.output/public - Root directory:
/(or subdirectory if monorepo) - Node version: 18 or later (set via
NODE_VERSIONenvironment variable)
Custom build command:
# Use specific package manager
npm ci && npm run build
# Or with bun
bun install && bun run build
# Or with pnpm
pnpm install --frozen-lockfile && pnpm run buildBuild Environment Variables
Set build-time variables:
NODE_VERSION = 18
NPM_VERSION = 10For Bun:
BUN_VERSION = 1.3.5---
Custom Domain Configuration
DNS Setup for Subdomain
For studio.yourdomain.com:
If domain on Cloudflare DNS:
- Automatic when adding custom domain in Pages
If domain on external DNS: 1. Add CNAME record:
- Name:
studio - Target:
your-project.pages.dev - Proxy status: DNS only (gray cloud)
2. Wait for DNS propagation 3. Verify: dig studio.yourdomain.com
SSL/TLS Configuration
Cloudflare provides automatic SSL:
1. SSL/TLS → Overview 2. Set to "Full" or "Full (strict)" 3. Universal SSL certificate covers subdomain 4. HTTPS enforced automatically
Redirect HTTP to HTTPS
Configure page rule:
1. Rules → Page Rules → Create Page Rule 2. URL: http://studio.yourdomain.com/* 3. Setting: Always Use HTTPS 4. Save and deploy
---
Deployment Workflows
Automatic Deployments (Pages)
Cloudflare Pages auto-deploys on git push:
1. Push to main branch → Production deployment 2. Push to other branches → Preview deployment 3. Pull requests → Preview deployments
Deployment URL pattern:
- Production:
studio.yourdomain.com - Preview:
[branch].[project].pages.dev
Manual Deployments (Workers)
Deploy manually with wrangler:
# Build and deploy
npm run build && wrangler deploy
# Deploy to specific environment
wrangler deploy --env productionCI/CD Integration
GitHub Actions example:
name: Deploy to Cloudflare Pages
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm ci
- run: npm run build
- uses: cloudflare/pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: your-project
directory: .output/public---
Troubleshooting Cloudflare Deployment
Build Fails on Cloudflare
Issue: Build succeeds locally but fails on Cloudflare
Solutions: 1. Check Node version matches: Set NODE_VERSION env var 2. Verify all dependencies in package.json 3. Check build logs for missing dependencies 4. Ensure nitro.preset is set to cloudflare-pages
Custom Domain Not Working
Issue: Subdomain returns 404 or connection errors
Solutions: 1. Verify DNS record exists and points correctly 2. Check SSL/TLS mode is "Full" or "Full (strict)" 3. Wait for DNS propagation (up to 48 hours) 4. Clear browser cache and DNS cache 5. Test with curl -I https://studio.yourdomain.com
OAuth Redirect Fails
Issue: Authentication redirects to wrong URL
Solutions: 1. Verify NUXT_PUBLIC_STUDIO_URL environment variable 2. Check OAuth app callback URL matches deployment URL 3. Ensure environment variables set for correct environment (production/preview) 4. Test callback URL: https://studio.yourdomain.com/api/auth/callback/github
Environment Variables Not Loading
Issue: Environment variables undefined at runtime
Solutions: 1. Verify variables set in Cloudflare dashboard 2. Check variable names match exactly (case-sensitive) 3. Redeploy after adding variables 4. For Workers: Use wrangler secret for sensitive data 5. Check if variables need NUXT_ prefix for Nuxt to recognize
---
Performance Optimization
Edge Caching
Configure Cloudflare caching for static assets:
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'cloudflare-pages',
cloudflare: {
pages: {
routes: {
include: ['/*'],
exclude: ['/api/*'] // Don't cache API routes
}
}
}
}
})Asset Optimization
Optimize static assets:
1. Images: Use Cloudflare Images or R2 for media library 2. Fonts: Serve from Cloudflare CDN 3. Scripts: Enable minification and compression
Regional Performance
Cloudflare automatically serves from nearest edge location. Monitor performance:
1. Analytics → Web Analytics 2. Check response times by region 3. Optimize based on geographic distribution
---
Cost Considerations
Cloudflare Pages Pricing
- Free tier: 500 builds/month, unlimited requests
- Paid tier: $20/month for 5,000 builds/month
Studio typically uses <100 builds/month on free tier.
Cloudflare Workers Pricing
- Free tier: 100,000 requests/day
- Paid tier: $5/month for 10M requests/month
Studio typically fits in free tier for small teams.
Custom Domain
No additional cost for custom subdomain on Cloudflare.
---
Next Steps
After deploying to Cloudflare:
1. Test thoroughly: Authentication, content editing, Git commits 2. Monitor deployments: Set up notifications for failed builds 3. Configure team access: Add team members to Cloudflare project 4. Set up backups: Regular content backups via Git 5. Document deployment: Share deployment URL and access instructions with team
Editor Configuration for Nuxt Studio
Complete guide for configuring Monaco, TipTap, and Form editors in Nuxt Studio.
Overview
Nuxt Studio provides three editor types that can be configured globally or per content type:
1. Monaco Editor: Code editor for markdown, YAML, JSON 2. TipTap Editor: Visual WYSIWYG editor with MDC component support (default) 3. Form Editor: Schema-driven form for YAML/JSON files
Default Editor Configuration
Set Global Default Editor
Configure in nuxt.config.ts:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/content', '@nuxt/studio'],
studio: {
editor: {
default: 'tiptap' // 'tiptap' | 'monaco' | 'form'
}
}
})Editor Selection Priority
Studio determines which editor to use:
1. User preference: User's last selected editor (stored in browser) 2. Content type: File extension-based configuration 3. Global default: Configured default editor 4. Fallback: TipTap (built-in default)
---
Monaco Editor
Monaco is the code editor from VS Code. Best for:
- Editing raw markdown with full syntax control
- Working with YAML frontmatter directly
- Editing JSON configuration files
- Developers comfortable with code editors
Enable Monaco as Default
export default defineNuxtConfig({
studio: {
editor: {
default: 'monaco'
}
}
})Monaco Configuration Options
export default defineNuxtConfig({
studio: {
editor: {
monaco: {
theme: 'vs-dark', // 'vs-light' | 'vs-dark' | 'hc-black'
fontSize: 14,
wordWrap: 'on', // 'off' | 'on' | 'wordWrapColumn' | 'bounded'
lineNumbers: 'on', // 'on' | 'off' | 'relative'
minimap: {
enabled: true
},
formatOnSave: true
}
}
}
})Monaco for Specific File Types
Configure Monaco for certain file extensions:
export default defineNuxtConfig({
studio: {
editor: {
default: 'tiptap', // Use TipTap by default
overrides: {
'.yaml': 'monaco', // Use Monaco for YAML files
'.json': 'monaco', // Use Monaco for JSON files
'.md': 'tiptap' // Use TipTap for markdown
}
}
}
})Monaco Features
Syntax Highlighting:
- Markdown
- YAML
- JSON
- HTML
- Vue components
IntelliSense:
- Auto-completion for YAML frontmatter
- Markdown syntax suggestions
- Vue component props (if configured)
Keybindings:
- Standard VS Code shortcuts
Cmd/Ctrl + S: SaveCmd/Ctrl + F: FindCmd/Ctrl + H: Replace
---
TipTap Editor (Default)
TipTap is a visual WYSIWYG editor. Best for:
- Content writers and non-technical users
- Visual editing without markdown syntax
- MDC component insertion
- Rich text formatting
Enable TipTap as Default
export default defineNuxtConfig({
studio: {
editor: {
default: 'tiptap'
}
}
})TipTap Configuration Options
export default defineNuxtConfig({
studio: {
editor: {
tiptap: {
toolbar: {
enabled: true,
items: [
'bold',
'italic',
'strike',
'code',
'heading',
'bulletList',
'orderedList',
'blockquote',
'codeBlock',
'link',
'image',
'table'
]
},
extensions: {
// Enable/disable specific extensions
bold: true,
italic: true,
strike: true,
code: true,
heading: { levels: [1, 2, 3, 4, 5, 6] },
link: true,
image: true,
codeBlock: { languages: ['javascript', 'typescript', 'vue', 'css'] }
}
}
}
}
})MDC Component Support
TipTap supports MDC (Markdown Components):
::alert{type="info"}
This is an info alert using MDC syntax
::
::code-block{language="typescript"}
const hello = 'world'
::Configure MDC components:
export default defineNuxtConfig({
content: {
experimental: {
clientDB: true // Enable client-side component rendering
}
},
studio: {
editor: {
tiptap: {
mdc: {
enabled: true,
components: ['Alert', 'CodeBlock', 'Card', 'Badge']
}
}
}
}
})TipTap Toolbar Customization
Customize toolbar buttons:
export default defineNuxtConfig({
studio: {
editor: {
tiptap: {
toolbar: {
items: [
'bold',
'italic',
'strike',
'|', // Separator
'heading',
'|',
'bulletList',
'orderedList',
'|',
'link',
'image',
'|',
'codeBlock',
'blockquote'
]
}
}
}
}
})TipTap Slash Commands
Enable slash commands for quick insertions:
export default defineNuxtConfig({
studio: {
editor: {
tiptap: {
slashCommands: {
enabled: true,
commands: [
{ name: 'heading1', label: 'Heading 1', icon: 'h1' },
{ name: 'heading2', label: 'Heading 2', icon: 'h2' },
{ name: 'bulletList', label: 'Bullet List', icon: 'list-ul' },
{ name: 'codeBlock', label: 'Code Block', icon: 'code' },
{ name: 'image', label: 'Image', icon: 'image' }
]
}
}
}
}
})Users can type / to show quick insertion menu.
---
Form Editor
Form editor is schema-driven for structured content. Best for:
- YAML configuration files
- JSON data files
- Structured metadata editing
- Non-technical users editing settings
Enable Form Editor
export default defineNuxtConfig({
studio: {
editor: {
default: 'form',
// Or for specific file types
overrides: {
'config.yaml': 'form',
'settings.json': 'form'
}
}
}
})Define Form Schemas
Create schemas for form-based editing:
// nuxt.config.ts
export default defineNuxtConfig({
studio: {
editor: {
form: {
schemas: {
// Schema for blog post frontmatter
'content/blog/*.md': {
fields: [
{
name: 'title',
type: 'string',
label: 'Title',
required: true
},
{
name: 'description',
type: 'text',
label: 'Description',
required: true
},
{
name: 'date',
type: 'date',
label: 'Publish Date',
required: true
},
{
name: 'tags',
type: 'array',
label: 'Tags',
itemType: 'string'
},
{
name: 'featured',
type: 'boolean',
label: 'Featured Post',
default: false
},
{
name: 'author',
type: 'select',
label: 'Author',
options: ['John Doe', 'Jane Smith', 'Bob Johnson']
},
{
name: 'category',
type: 'select',
label: 'Category',
options: [
{ label: 'Technology', value: 'tech' },
{ label: 'Design', value: 'design' },
{ label: 'Business', value: 'business' }
]
}
]
}
}
}
}
}
})Form Field Types
Supported field types:
- string: Single-line text input
- text: Multi-line textarea
- number: Numeric input
- boolean: Checkbox
- date: Date picker
- datetime: Date and time picker
- select: Dropdown selection
- array: List of items
- object: Nested object
- image: Image upload/selector
- file: File upload/selector
Form Validation
Add validation rules:
{
name: 'email',
type: 'string',
label: 'Email',
required: true,
validation: {
pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
message: 'Please enter a valid email address'
}
}Conditional Fields
Show fields based on other field values:
{
name: 'postType',
type: 'select',
label: 'Post Type',
options: ['article', 'video', 'podcast']
},
{
name: 'videoUrl',
type: 'string',
label: 'Video URL',
condition: {
field: 'postType',
value: 'video'
}
}---
Per-Collection Configuration
Configure editors for specific content collections:
export default defineNuxtConfig({
studio: {
collections: {
blog: {
editor: 'tiptap', // Blog posts use TipTap
tiptap: {
toolbar: {
items: ['bold', 'italic', 'link', 'heading', 'image']
}
}
},
docs: {
editor: 'monaco', // Docs use Monaco for precise editing
monaco: {
theme: 'vs-dark'
}
},
config: {
editor: 'form', // Config files use Form editor
form: {
schema: {
fields: [
{ name: 'siteName', type: 'string', required: true },
{ name: 'siteUrl', type: 'string', required: true },
{ name: 'analytics', type: 'boolean' }
]
}
}
}
}
}
})---
Media Library Configuration
Configure media library for image/file uploads:
export default defineNuxtConfig({
studio: {
media: {
enabled: true,
storage: 'cloudflare-r2', // 'local' | 'cloudflare-r2' | 's3'
formats: ['jpeg', 'png', 'gif', 'webp', 'avif', 'svg'],
maxFileSize: 10 * 1024 * 1024, // 10MB
thumbnails: {
enabled: true,
sizes: [
{ width: 200, height: 200, name: 'thumb' },
{ width: 800, height: 600, name: 'medium' },
{ width: 1920, height: 1080, name: 'large' }
]
}
}
}
})Cloudflare R2 for Media
Configure R2 bucket for Studio media:
export default defineNuxtConfig({
studio: {
media: {
storage: 'cloudflare-r2',
r2: {
accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
bucketName: 'studio-media',
publicUrl: 'https://media.yourdomain.com'
}
}
}
})---
Editor Switching
Allow users to switch between editors:
export default defineNuxtConfig({
studio: {
editor: {
allowSwitching: true, // Show editor switcher in UI
default: 'tiptap',
available: ['tiptap', 'monaco'] // Available editors for user
}
}
})Users see a dropdown to switch between available editors.
---
Custom Editor Themes
Monaco Themes
export default defineNuxtConfig({
studio: {
editor: {
monaco: {
theme: 'vs-dark', // Built-in: 'vs-light', 'vs-dark', 'hc-black'
// Or define custom theme
customTheme: {
base: 'vs-dark',
inherit: true,
rules: [
{ token: 'comment', foreground: '6A9955' },
{ token: 'keyword', foreground: '569CD6' }
],
colors: {
'editor.background': '#1E1E1E',
'editor.foreground': '#D4D4D4'
}
}
}
}
}
})TipTap Themes
export default defineNuxtConfig({
studio: {
editor: {
tiptap: {
theme: {
backgroundColor: '#ffffff',
textColor: '#1a202c',
accentColor: '#3b82f6',
borderColor: '#e5e7eb'
}
}
}
}
})---
Accessibility Configuration
Configure accessibility features:
export default defineNuxtConfig({
studio: {
editor: {
accessibility: {
highContrast: true,
keyboardNavigation: true,
screenReaderSupport: true,
fontSize: {
min: 12,
max: 24,
default: 14
}
}
}
}
})---
Editor Performance
Monaco Performance
export default defineNuxtConfig({
studio: {
editor: {
monaco: {
// Disable features for better performance
minimap: { enabled: false },
lineNumbers: 'off',
folding: false,
renderWhitespace: 'none'
}
}
}
})TipTap Performance
export default defineNuxtConfig({
studio: {
editor: {
tiptap: {
// Lazy load extensions
lazyExtensions: true,
// Debounce save
saveDebounce: 500, // ms
// Limit history
history: {
depth: 100 // Undo/redo depth
}
}
}
}
})---
Best Practices
Editor Selection by Use Case
Choose Monaco when:
- Users are developers or technical writers
- Precise control over markdown syntax needed
- Working with YAML/JSON configuration files
- Users prefer code editors
Choose TipTap when:
- Users are content writers or non-technical
- Visual formatting is important
- MDC components are heavily used
- Rich text editing needed
Choose Form when:
- Content has strict structure
- Users are non-technical
- Validation and constraints required
- Editing configuration files
Progressive Enhancement
Start with TipTap (visual) and allow switching to Monaco:
export default defineNuxtConfig({
studio: {
editor: {
default: 'tiptap',
allowSwitching: true,
available: ['tiptap', 'monaco']
}
}
})Testing Editors
Test all configured editors:
1. Create test content file 2. Open in Studio 3. Test each editor type 4. Verify formatting preserved 5. Check MDC component rendering 6. Test save and Git commit
---
Troubleshooting
Editor Not Loading
Issue: Editor UI blank or shows error
Solutions: 1. Check browser console for JavaScript errors 2. Verify Studio module installed correctly 3. Clear browser cache 4. Check Nuxt Content module is loaded first 5. Verify content directory exists
Monaco Theme Not Applying
Issue: Custom Monaco theme not visible
Solutions: 1. Verify theme configuration in nuxt.config.ts 2. Check theme JSON syntax 3. Reload Studio page 4. Try built-in themes first ('vs-dark', 'vs-light')
TipTap Toolbar Missing
Issue: Toolbar not showing in TipTap editor
Solutions: 1. Check toolbar.enabled: true in config 2. Verify toolbar items are valid 3. Check for CSS conflicts 4. Inspect element in browser DevTools
Form Editor Schema Not Working
Issue: Form fields not appearing
Solutions: 1. Verify schema syntax in nuxt.config.ts 2. Check field types are valid 3. Match schema path pattern to content file 4. Test with simple schema first
---
Next Steps
After configuring editors:
1. Test all editor types with sample content 2. Train users on editor features and shortcuts 3. Document editor choice for different content types 4. Monitor performance and adjust settings 5. Collect feedback from content editors
OAuth Provider Setup for Nuxt Studio
Complete guide for configuring OAuth authentication with GitHub, GitLab, and Google.
Overview
Nuxt Studio requires OAuth authentication for production deployments. Each provider requires creating an OAuth app and configuring environment variables.
GitHub OAuth Setup
1. Create GitHub OAuth App
1. Go to https://github.com/settings/developers 2. Click "OAuth Apps" → "New OAuth App" 3. Fill in the application details:
- Application name:
Your Site - Studio CMS - Homepage URL:
https://yourdomain.com - Authorization callback URL:
https://studio.yourdomain.com/api/auth/callback/github
4. Click "Register application" 5. Note the Client ID 6. Click "Generate a new client secret" and copy the secret immediately
2. Configure Environment Variables
Add to your .env file (local development):
NUXT_OAUTH_GITHUB_CLIENT_ID=your_github_client_id
NUXT_OAUTH_GITHUB_CLIENT_SECRET=your_github_client_secret3. Set Variables on Cloudflare
For Cloudflare Pages: 1. Go to Workers & Pages → Select your project 2. Click Settings → Environment variables 3. Add variables:
- Name:
NUXT_OAUTH_GITHUB_CLIENT_ID - Value: Your GitHub Client ID
- Name:
NUXT_OAUTH_GITHUB_CLIENT_SECRET - Value: Your GitHub Client Secret
4. Deploy to production and preview environments
4. Verify Configuration
Test authentication: 1. Visit https://studio.yourdomain.com 2. Click "Sign in with GitHub" 3. Authorize the application 4. Should redirect back to Studio dashboard
Troubleshooting:
- If redirect fails, verify callback URL matches exactly
- Check that environment variables are set correctly
- Ensure deployment URL uses HTTPS
---
GitLab OAuth Setup
1. Create GitLab OAuth Application
For GitLab.com: 1. Go to https://gitlab.com/-/profile/applications 2. Fill in application details:
- Name:
Your Site - Studio CMS - Redirect URI:
https://studio.yourdomain.com/api/auth/callback/gitlab - Confidential: ✅ Check this box
- Scopes: Select
read_user,read_repository,write_repository
3. Click "Save application" 4. Copy Application ID and Secret
For Self-Hosted GitLab: 1. Go to https://your-gitlab.com/-/profile/applications 2. Follow same steps as GitLab.com 3. Ensure your GitLab instance is accessible from Studio deployment
2. Configure Environment Variables
Add to .env:
NUXT_OAUTH_GITLAB_CLIENT_ID=your_gitlab_application_id
NUXT_OAUTH_GITLAB_CLIENT_SECRET=your_gitlab_secretFor self-hosted GitLab, also add:
NUXT_OAUTH_GITLAB_SERVER_URL=https://your-gitlab.com3. Set Variables on Cloudflare
Same process as GitHub OAuth: 1. Workers & Pages → Project → Settings → Environment variables 2. Add:
NUXT_OAUTH_GITLAB_CLIENT_IDNUXT_OAUTH_GITLAB_CLIENT_SECRETNUXT_OAUTH_GITLAB_SERVER_URL(if self-hosted)
4. Verify Configuration
1. Visit https://studio.yourdomain.com 2. Click "Sign in with GitLab" 3. Authorize the application 4. Verify redirect back to Studio
Troubleshooting:
- For self-hosted: Verify
NUXT_OAUTH_GITLAB_SERVER_URLis correct - Check OAuth app scopes include repository write access
- Ensure confidential setting is enabled
---
Google OAuth Setup
1. Create Google OAuth Client
1. Go to https://console.cloud.google.com/apis/credentials 2. Create a new project or select existing project 3. Click "Create Credentials" → "OAuth client ID" 4. Configure OAuth consent screen (if first time):
- User Type: External
- App name:
Your Site Studio - User support email: Your email
- Authorized domains:
yourdomain.com
5. Create OAuth client ID:
- Application type: Web application
- Name:
Studio CMS - Authorized JavaScript origins:
https://studio.yourdomain.com - Authorized redirect URIs:
https://studio.yourdomain.com/api/auth/callback/google
6. Click "Create" 7. Copy Client ID and Client Secret
2. Configure Environment Variables
Add to .env:
NUXT_OAUTH_GOOGLE_CLIENT_ID=your_google_client_id
NUXT_OAUTH_GOOGLE_CLIENT_SECRET=your_google_client_secret3. Set Variables on Cloudflare
Same process: 1. Workers & Pages → Project → Settings → Environment variables 2. Add:
NUXT_OAUTH_GOOGLE_CLIENT_IDNUXT_OAUTH_GOOGLE_CLIENT_SECRET
4. Verify Configuration
1. Visit https://studio.yourdomain.com 2. Click "Sign in with Google" 3. Choose Google account 4. Grant permissions 5. Verify redirect to Studio
Troubleshooting:
- Ensure authorized redirect URI matches deployment URL exactly
- Check OAuth consent screen is published (not in testing mode for production)
- Verify authorized domains include your domain
---
Multiple OAuth Providers
You can configure multiple providers simultaneously. Users will see all configured options on the login screen.
Example with all three:
# GitHub
NUXT_OAUTH_GITHUB_CLIENT_ID=github_client_id
NUXT_OAUTH_GITHUB_CLIENT_SECRET=github_secret
# GitLab
NUXT_OAUTH_GITLAB_CLIENT_ID=gitlab_app_id
NUXT_OAUTH_GITLAB_CLIENT_SECRET=gitlab_secret
# Google
NUXT_OAUTH_GOOGLE_CLIENT_ID=google_client_id
NUXT_OAUTH_GOOGLE_CLIENT_SECRET=google_secretStudio will automatically detect configured providers and show appropriate login buttons.
---
Security Best Practices
Never Commit Secrets
❌ Never do this:
# .env committed to Git
NUXT_OAUTH_GITHUB_CLIENT_SECRET=abc123secret✅ Do this:
# .env.example (committed to Git)
NUXT_OAUTH_GITHUB_CLIENT_ID=
NUXT_OAUTH_GITHUB_CLIENT_SECRET=
# .env (in .gitignore)
NUXT_OAUTH_GITHUB_CLIENT_ID=actual_id
NUXT_OAUTH_GITHUB_CLIENT_SECRET=actual_secretUse Environment-Specific Secrets
For Cloudflare Pages, use different OAuth apps for:
- Production:
studio.yourdomain.com - Preview:
*.pages.dev
This isolates environments and improves security.
Rotate Secrets Regularly
- Regenerate OAuth secrets quarterly
- Update environment variables on all platforms
- Test authentication after rotation
---
OAuth Callback URL Patterns
Production
https://studio.yourdomain.com/api/auth/callback/[provider]Preview (Cloudflare Pages)
https://[branch].[project].pages.dev/api/auth/callback/[provider]Local Development
http://localhost:3000/api/auth/callback/[provider]Create separate OAuth apps for each environment or add multiple callback URLs to the same app (if provider allows).
---
Common OAuth Issues
Issue: "redirect_uri_mismatch"
Cause: OAuth app callback URL doesn't match actual URL
Solution: 1. Check OAuth app settings 2. Verify callback URL is exact (including HTTPS, subdomain, path) 3. Update OAuth app if deployment URL changed
Issue: "invalid_client"
Cause: Client ID or secret is incorrect
Solution: 1. Verify environment variables are set correctly 2. Check for typos in client ID/secret 3. Regenerate secret if needed
Issue: "access_denied"
Cause: User denied authorization or app lacks permissions
Solution: 1. Ensure required scopes are configured (read/write repository) 2. Re-authorize the application 3. Check OAuth app is approved for production use
---
Testing OAuth Locally
Before deploying to production, test OAuth locally:
1. Set up local environment variables:
# .env.local
NUXT_OAUTH_GITHUB_CLIENT_ID=local_test_id
NUXT_OAUTH_GITHUB_CLIENT_SECRET=local_test_secret2. Create development OAuth app with callback:
http://localhost:3000/api/auth/callback/github3. Start dev server:
npm run dev4. Test authentication:
- Visit
http://localhost:3000/_studio - Click "Sign in with GitHub"
- Verify redirect and authentication
5. Debug with console:
- Check browser console for errors
- Verify network requests to
/api/auth/ - Check server logs for OAuth errors
---
Advanced Configuration
Custom OAuth Scopes
Configure custom scopes in nuxt.config.ts:
export default defineNuxtConfig({
oauth: {
github: {
clientId: process.env.NUXT_OAUTH_GITHUB_CLIENT_ID,
clientSecret: process.env.NUXT_OAUTH_GITHUB_CLIENT_SECRET,
scope: ['read:user', 'repo', 'workflow'] // Custom scopes
}
}
})OAuth Session Configuration
export default defineNuxtConfig({
auth: {
session: {
cookie: {
secure: true, // HTTPS only
httpOnly: true, // No JavaScript access
sameSite: 'lax' // CSRF protection
},
maxAge: 60 * 60 * 24 * 7 // 7 days
}
}
})---
Provider Comparison
| Feature | GitHub | GitLab | |
|---|---|---|---|
| Self-hosted support | ❌ No | ✅ Yes | ❌ No |
| Private repos | ✅ Yes | ✅ Yes | N/A |
| Team management | ✅ Organizations | ✅ Groups | ❌ Limited |
| Setup complexity | ⭐⭐ Easy | ⭐⭐ Easy | ⭐⭐⭐ Moderate |
| Best for | Public repos, GitHub users | Self-hosted, GitLab users | Universal access |
Recommendation: Use GitHub OAuth for most cases. Use GitLab for self-hosted instances. Use Google for universal access without GitHub/GitLab accounts.
---
Next Steps
After configuring OAuth: 1. Test authentication thoroughly 2. Configure user permissions (if needed) 3. Set up team access (Organizations/Groups) 4. Document authentication flow for team members 5. Monitor OAuth errors in production logs
Subdomain Setup for Nuxt Studio
Complete guide for configuring custom subdomains (studio.domain.com, cms.domain.com) for Nuxt Studio deployments.
Overview
Deploying Studio to a subdomain provides:
- Clean separation between main site and CMS
- Professional appearance for content editors
- Easy OAuth callback URL configuration
- Better security isolation
Common subdomain patterns:
studio.yourdomain.comcms.yourdomain.comedit.yourdomain.comadmin.yourdomain.com
DNS Configuration
Option 1: Domain on Cloudflare DNS
If your domain uses Cloudflare nameservers:
1. Cloudflare Pages automatically creates DNS record:
- Go to Pages project → Custom domains
- Click "Set up a custom domain"
- Enter:
studio.yourdomain.com - Cloudflare creates CNAME record automatically
2. DNS Record Created:
Type: CNAME
Name: studio
Target: your-project.pages.dev
Proxy status: Proxied (orange cloud)
TTL: Auto3. Verify DNS:
dig studio.yourdomain.com
# or
nslookup studio.yourdomain.comOption 2: Domain on External DNS Provider
If your domain is managed elsewhere (GoDaddy, Namecheap, etc.):
1. Add CNAME record in your DNS provider:
- Type: CNAME
- Name:
studio(or@studiodepending on provider) - Target/Value:
your-project.pages.dev - TTL: 3600 (or Auto)
2. Wait for DNS propagation:
- Usually 5-30 minutes
- Can take up to 48 hours in rare cases
3. Verify propagation:
dig studio.yourdomain.com
# Should show CNAME pointing to *.pages.devOption 3: Cloudflare as DNS Proxy (Recommended)
Use Cloudflare for DNS even if not hosting there:
1. Change nameservers to Cloudflare:
- Sign up at cloudflare.com
- Add domain
- Update nameservers at your registrar
- Wait for nameserver propagation (24-48 hours)
2. Add CNAME record in Cloudflare DNS:
- Type: CNAME
- Name: studio
- Target: your-project.pages.dev
- Proxy status: Proxied (orange cloud) - enables Cloudflare features
- TTL: Auto
3. Benefits:
- Free SSL/TLS certificates
- DDoS protection
- Caching and CDN
- Analytics
---
SSL/TLS Configuration
Cloudflare SSL
Cloudflare provides automatic SSL for subdomains:
1. SSL/TLS Mode:
- Go to SSL/TLS → Overview
- Set to "Full" or "Full (strict)" (recommended)
- Universal SSL covers subdomain automatically
2. Force HTTPS:
- SSL/TLS → Edge Certificates
- Enable "Always Use HTTPS"
- Redirects HTTP to HTTPS automatically
3. HSTS (Optional but recommended):
- SSL/TLS → Edge Certificates
- Enable "HTTP Strict Transport Security (HSTS)"
- Max Age: 12 months (recommended)
Custom SSL Certificate (Advanced)
For custom SSL certificates:
1. Upload certificate:
- SSL/TLS → Edge Certificates → Upload Custom SSL
- Provide certificate, private key, and chain
2. Configure for subdomain:
- Ensure certificate includes subdomain in SAN (Subject Alternative Names)
- Example:
*.yourdomain.comorstudio.yourdomain.com
---
Cloudflare Pages Custom Domain Setup
Add Custom Domain
1. Navigate to Pages project:
- Workers & Pages → Select your Studio project
- Click Custom domains tab
2. Set up custom domain:
- Click "Set up a custom domain"
- Enter subdomain:
studio.yourdomain.com - Click "Continue"
3. DNS Configuration:
- If domain on Cloudflare DNS: Automatically configured
- If external DNS: Follow instructions to add CNAME record
4. Verify domain:
- Status shows "Active" when ready
- Usually takes 5-15 minutes
Multiple Subdomains
Add multiple subdomains to same project:
studio.yourdomain.com → Production
staging.yourdomain.com → Staging
preview.yourdomain.com → Preview buildsEach subdomain can point to different branch or environment.
---
Cloudflare Workers Custom Routes
For Workers deployment (not Pages), configure routes:
Via wrangler.toml
# wrangler.toml
name = "studio-cms"
main = "./.output/server/index.mjs"
routes = [
{ pattern = "studio.yourdomain.com/*", zone_name = "yourdomain.com" }
]Via Dashboard
1. Workers & Pages → Select Worker → Routes 2. Click "Add route" 3. Configure:
- Route:
studio.yourdomain.com/* - Zone: Select
yourdomain.com - Worker: Select your Studio worker
4. Click "Save"
Wildcard Routes
For preview branches:
routes = [
{ pattern = "*.studio.yourdomain.com/*", zone_name = "yourdomain.com" }
]This enables main.studio.yourdomain.com, dev.studio.yourdomain.com, etc.
---
OAuth Callback URL Configuration
After subdomain is configured, update OAuth apps:
GitHub OAuth
1. Go to OAuth app settings 2. Update "Authorization callback URL":
https://studio.yourdomain.com/api/auth/callback/githubGitLab OAuth
1. Go to OAuth application settings 2. Update "Redirect URI":
https://studio.yourdomain.com/api/auth/callback/gitlabGoogle OAuth
1. Go to Google Cloud Console → OAuth client 2. Update "Authorized redirect URIs":
https://studio.yourdomain.com/api/auth/callback/googleTesting Callbacks
Test OAuth callbacks with:
curl -I https://studio.yourdomain.com/api/auth/callback/github
# Should return 405 Method Not Allowed (expected - needs POST)If returns 404, check deployment and routing configuration.
---
Environment Variables for Subdomain
Set Studio URL environment variable:
Cloudflare Pages
1. Workers & Pages → Project → Settings → Environment variables 2. Add variable:
- Name:
NUXT_PUBLIC_STUDIO_URL - Value:
https://studio.yourdomain.com - Environment: Production
Nuxt Configuration
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
public: {
studioUrl: process.env.NUXT_PUBLIC_STUDIO_URL || 'http://localhost:3000'
}
}
})---
Subdomain Routing Patterns
Single Subdomain
Most common: One subdomain for Studio
Main site: https://yourdomain.com
Studio CMS: https://studio.yourdomain.comMulti-Environment Subdomains
Separate subdomains for each environment:
Production: https://studio.yourdomain.com
Staging: https://studio-staging.yourdomain.com
Development: https://studio-dev.yourdomain.comBranch-Based Subdomains
Cloudflare Pages automatic preview deployments:
Main: https://studio.yourdomain.com
PR #123: https://123.studio.yourdomain.com
Branch dev: https://dev.studio.yourdomain.com---
Vercel/Netlify Subdomain Setup
If deploying to platforms other than Cloudflare:
Vercel
1. Add custom domain in project settings 2. Enter: studio.yourdomain.com 3. Add DNS record:
- Type: CNAME
- Name: studio
- Value: cname.vercel-dns.com
4. Wait for verification
Netlify
1. Domain management → Add custom domain 2. Enter: studio.yourdomain.com 3. Add DNS record:
- Type: CNAME
- Name: studio
- Value: [your-site].netlify.app
4. Enable HTTPS in Netlify dashboard
---
Troubleshooting Subdomain Issues
Subdomain Returns 404
Causes:
- DNS not propagated yet
- CNAME record incorrect
- Custom domain not added in deployment platform
- Routing configuration missing
Solutions:
# Check DNS resolution
dig studio.yourdomain.com
# Verify CNAME points correctly
nslookup studio.yourdomain.com
# Clear local DNS cache (macOS)
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
# Clear local DNS cache (Windows)
ipconfig /flushdns
# Check from external DNS checker
# https://www.whatsmydns.net/#CNAME/studio.yourdomain.comSSL Certificate Errors
Causes:
- Certificate doesn't cover subdomain
- SSL mode misconfigured
- Certificate not yet issued
Solutions: 1. Verify SSL/TLS mode is "Full" or "Full (strict)" 2. Wait 15 minutes for certificate issuance 3. Check universal SSL includes subdomain 4. Force HTTPS redirect enabled
Redirect Loop
Causes:
- SSL/TLS mode set to "Flexible" with HTTPS redirect
- Duplicate redirect rules
Solutions: 1. Change SSL/TLS mode to "Full" 2. Remove duplicate redirect rules 3. Check page rules for conflicts
DNS Propagation Delays
Causes:
- TTL too high on old record
- DNS cache at ISP level
Solutions: 1. Wait longer (up to 48 hours maximum) 2. Check from multiple locations: https://www.whatsmydns.net 3. Try different DNS servers: nslookup studio.yourdomain.com 8.8.8.8 4. Lower TTL before making changes (plan ahead)
---
Best Practices
DNS Best Practices
1. Use CNAME, not A record for subdomains:
- CNAME follows if deployment IP changes
- A record requires manual updates
2. Enable Cloudflare proxy (orange cloud):
- Free SSL/TLS
- DDoS protection
- Performance improvements
3. Set reasonable TTL:
- For active development: 300 (5 minutes)
- For production: 3600 (1 hour)
- For stable: 86400 (24 hours)
Security Best Practices
1. Always use HTTPS:
- Force HTTPS redirect
- Enable HSTS
2. Separate OAuth apps per environment:
- Production: studio.yourdomain.com
- Staging: studio-staging.yourdomain.com
3. Restrict access if needed:
- Cloudflare Access for IP allowlisting
- HTTP Basic Auth for staging
Naming Conventions
Choose clear, professional subdomain names:
Good:
studio.yourdomain.com- Clear purposecms.yourdomain.com- Industry standardedit.yourdomain.com- Descriptive
Avoid:
admin.yourdomain.com- Too generic, security riskbackend.yourdomain.com- Confusingnuxt.yourdomain.com- Technology-specific
---
Verification Checklist
Before going live with subdomain:
- [ ] DNS record created and propagated
- [ ] Subdomain resolves to correct target
- [ ] SSL certificate active and valid
- [ ] HTTPS redirect enabled
- [ ] Custom domain added in deployment platform
- [ ] OAuth callback URLs updated
- [ ] Environment variable set for Studio URL
- [ ] Test OAuth authentication works
- [ ] Test content editing functionality
- [ ] Verify Git commits work
- [ ] Check subdomain accessible from multiple networks
---
Monitoring and Maintenance
Monitor Subdomain Health
1. Set up uptime monitoring:
- Use Cloudflare Health Checks
- Or external service (UptimeRobot, Pingdom)
2. Monitor SSL certificate expiration:
- Cloudflare automatic renewal
- Set reminder 30 days before manual certificates expire
3. Check DNS resolution:
- Weekly checks for DNS issues
- Monitor DNS propagation after changes
Maintenance Tasks
Monthly:
- Verify SSL certificate valid
- Check uptime metrics
- Review access logs for issues
Quarterly:
- Review subdomain naming relevance
- Check for DNS optimization opportunities
- Update documentation if subdomain changes
Annually:
- Audit all subdomains in use
- Remove unused subdomains
- Review security settings
---
Next Steps
After subdomain is configured and working:
1. Document subdomain for team members 2. Update all references to Studio URL in documentation 3. Configure monitoring for uptime and SSL 4. Test from multiple locations to verify global accessibility 5. Train team on accessing Studio via subdomain
Troubleshooting Nuxt Studio
Comprehensive error catalog and solutions for common Nuxt Studio issues.
Table of Contents
1. Installation Errors 2. OAuth Authentication Errors 3. Cloudflare Deployment Errors 4. Editor Issues 5. Content Editing Issues 6. Git Integration Issues 7. Performance Issues 8. Configuration Errors
---
Installation Errors
Error: Module not found: '@nuxt/studio'
Symptom: Build fails with "Cannot find module '@nuxt/studio'"
Cause: Studio module not installed or installed incorrectly
Solution:
# Install using nuxi (recommended)
npx nuxi module add nuxt-studio@beta
# Or manually
npm install -D nuxt-studio@beta
# Verify in package.json
grep "nuxt-studio" package.jsonVerify nuxt.config.ts includes:
export default defineNuxtConfig({
modules: ['@nuxt/content', '@nuxt/studio']
})---
Error: '@nuxt/content' is required
Symptom: "Nuxt Studio requires @nuxt/content to be installed"
Cause: Nuxt Content module missing (required dependency)
Solution:
# Install Nuxt Content first
npx nuxi module add content
# Then install Studio
npx nuxi module add nuxt-studio@beta
# Verify both in nuxt.config.ts
# Order matters: content before studio
export default defineNuxtConfig({
modules: [
'@nuxt/content', // Must be first
'@nuxt/studio'
]
})---
Error: Nuxt version incompatibility
Symptom: "Studio requires Nuxt >=3.0.0"
Cause: Using Nuxt 2.x or outdated Nuxt 3
Solution:
# Check current Nuxt version
npm list nuxt
# Upgrade to Nuxt 3.x
npm install nuxt@latest
# Or use Nuxt 4 (recommended)
npm install nuxt@rcMigration: If upgrading from Nuxt 2, follow https://nuxt.com/docs/migration/overview
---
OAuth Authentication Errors
Error: OAuth redirect_uri_mismatch
Symptom: OAuth login redirects to error page: "The redirect_uri in the request does not match the ones authorized for the OAuth client"
Cause: OAuth app callback URL doesn't match deployment URL
Solution:
1. Check deployed Studio URL:
# Should match OAuth callback URL exactly
https://studio.yourdomain.com2. Update OAuth app (example for GitHub):
- Go to https://github.com/settings/developers
- Select your OAuth app
- Update "Authorization callback URL":
https://studio.yourdomain.com/api/auth/callback/github- Save changes
3. Common mistakes:
❌ http://studio.yourdomain.com/... (HTTP instead of HTTPS)
❌ https://yourdomain.com/api/auth/... (Wrong subdomain)
❌ https://studio.yourdomain.com/api/auth/callback/Github (Capital G)
✅ https://studio.yourdomain.com/api/auth/callback/github4. For multiple environments, create separate OAuth apps:
- Production:
https://studio.yourdomain.com/api/auth/callback/github - Preview:
https://preview.yourdomain.com/api/auth/callback/github - Local:
http://localhost:3000/api/auth/callback/github
---
Error: Authentication loop (redirect loop)
Symptom: After OAuth login, continuously redirects back to login page
Cause: Session cookies not persisting
Solutions:
1. Check environment variables:
# Must match deployment URL exactly
NUXT_PUBLIC_STUDIO_URL=https://studio.yourdomain.com2. Verify HTTPS is used (not HTTP):
- OAuth cookies require
secureflag - Only works over HTTPS in production
3. Check browser cookie settings:
- Allow cookies for studio.yourdomain.com
- Allow third-party cookies (for OAuth flow)
- Try in incognito mode to rule out extensions
4. Verify Cloudflare SSL mode:
❌ Flexible (causes loops)
✅ Full or Full (strict)5. Clear browser cookies and retry:
# Clear cookies for studio.yourdomain.com
# Then try authentication again---
Error: invalid_client
Symptom: OAuth error "invalid_client" or "unauthorized_client"
Cause: Client ID or secret incorrect or missing
Solution:
1. Verify environment variables:
# Check in Cloudflare dashboard or .env
NUXT_OAUTH_GITHUB_CLIENT_ID=your_client_id_here
NUXT_OAUTH_GITHUB_CLIENT_SECRET=your_secret_here2. Regenerate OAuth credentials if lost:
- GitHub: Settings → Developer settings → OAuth Apps → Generate new secret
- Copy new secret immediately (shown only once)
- Update environment variable
3. Check for typos:
- Client ID should be exactly as shown in OAuth app
- No extra spaces or characters
4. Redeploy after updating variables:
# Cloudflare Pages: Push to Git to trigger deployment
git commit --allow-empty -m "Redeploy with updated OAuth credentials"
git push---
Error: access_denied
Symptom: OAuth login fails with "access_denied" error
Cause: User denied authorization or app lacks required permissions
Solutions:
1. Check OAuth scopes (GitHub example):
// Ensure app has required scopes
// For Studio: read_user, repo (or public_repo for public repos only)2. Re-authorize application:
- Revoke access in GitHub/GitLab/Google settings
- Try logging in again
- Grant all requested permissions
3. For GitHub, check app is approved:
- Go to OAuth app settings
- Ensure "User authorization callback URL" is set
- App should not be in "suspended" state
4. For Google, verify consent screen:
- OAuth consent screen must be published (not in testing mode for production)
- User must be within allowed user group (if restricted)
---
Cloudflare Deployment Errors
Error: Build fails on Cloudflare Pages
Symptom: Build succeeds locally but fails on Cloudflare
Causes and Solutions:
1. Wrong Node version:
# Set environment variable in Cloudflare Pages
NODE_VERSION=182. Missing dependencies:
# Ensure all dependencies in package.json
npm install
# Check package.json for missing deps3. Wrong build output directory:
# Should be set to:
.output/public
# NOT:
dist/ or .nuxt/ or build/4. Nitro preset not configured:
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'cloudflare-pages' // Required!
}
})5. Build command incorrect:
# Should be:
npm run build
# Or if using Bun:
bun run build---
Error: Incompatible module warnings
Symptom: "Module X may not be compatible with Cloudflare runtime"
Cause: Module uses Node.js-specific APIs not available in Workers/Pages
Solutions:
1. Check module compatibility with Cloudflare:
- Search for "cloudflare" compatibility in module docs
- Look for "edge runtime" or "edge compatible"
2. Use edge-compatible alternatives:
❌ bcrypt → ✅ bcrypt-edge
❌ fs module → ✅ R2 or KV storage
❌ child_process → ✅ Cloudflare Workers (no subprocess support)3. Exclude incompatible modules from edge build:
export default defineNuxtConfig({
nitro: {
externals: {
inline: ['incompatible-module']
}
}
})---
Error: 404 on custom subdomain
Symptom: Main site works but studio.domain.com returns 404
Solutions:
1. Verify DNS record:
dig studio.yourdomain.com
# Should show CNAME to *.pages.dev2. Check custom domain added in Cloudflare Pages:
- Workers & Pages → Project → Custom domains
- Should show
studio.yourdomain.comas "Active"
3. Wait for DNS propagation:
# Check propagation globally
# https://www.whatsmydns.net4. Verify routing configuration (for Workers):
# wrangler.toml
routes = [
{ pattern = "studio.yourdomain.com/*", zone_name = "yourdomain.com" }
]---
Editor Issues
Error: Editor shows blank screen
Symptom: Studio loads but editor area is blank/white
Solutions:
1. Check browser console for errors:
- Open DevTools (F12)
- Look for JavaScript errors
- Common: Module loading failures
2. Clear browser cache:
# Hard refresh:
Ctrl+Shift+R (Windows/Linux)
Cmd+Shift+R (macOS)3. Verify content directory exists:
# Should have content/ directory with files
ls -la content/4. Check Nuxt Content configuration:
export default defineNuxtConfig({
content: {
// Should have basic config
}
})5. Try different browser:
- Test in Chrome, Firefox, Safari
- Rules out browser-specific issues
---
Error: Monaco editor not loading
Symptom: Monaco editor requested but TipTap loads instead
Cause: Monaco configuration issue or user preference
Solutions:
1. Clear user preferences:
// In browser console
localStorage.clear()
// Reload page2. Check editor configuration:
export default defineNuxtConfig({
studio: {
editor: {
default: 'monaco', // Explicitly set
available: ['monaco', 'tiptap']
}
}
})3. Verify Monaco not disabled:
export default defineNuxtConfig({
studio: {
editor: {
available: ['monaco'] // Ensure Monaco in list
}
}
})---
Error: TipTap toolbar missing
Symptom: TipTap editor loads but toolbar is not visible
Solutions:
1. Check toolbar configuration:
export default defineNuxtConfig({
studio: {
editor: {
tiptap: {
toolbar: {
enabled: true // Must be true
}
}
}
}
})2. Inspect element:
- Open DevTools
- Check if toolbar exists but hidden (CSS issue)
- Look for
display: noneorvisibility: hidden
3. Clear CSS cache:
- Hard refresh browser
- Check for conflicting CSS from custom styles
---
Content Editing Issues
Error: Changes not saving
Symptom: Edit content but changes don't persist
Solutions:
1. Check Git integration:
- Studio requires Git for persistence
- Ensure
.gitdirectory exists
2. Verify write permissions:
- User must have write access to repository
- Check GitHub/GitLab repository permissions
3. Check browser console:
- Look for save errors
- Check network tab for failed API calls
4. Verify OAuth scopes:
- GitHub: Must have
reposcope (orpublic_repofor public repos) - GitLab: Must have
write_repositoryscope
5. Test manual Git commit:
# Try committing directly
git add content/
git commit -m "Test commit"
git push
# If fails, check Git configuration---
Error: MDC components not rendering
Symptom: MDC syntax shows as plain text instead of components
Cause: Client DB or component registration not configured
Solutions:
1. Enable client DB:
export default defineNuxtConfig({
content: {
experimental: {
clientDB: true // Required for MDC in Studio
}
}
})2. Register MDC components:
export default defineNuxtConfig({
components: {
dirs: [
'~/components/content' // MDC components directory
]
}
})3. Verify component exists:
# Check component file exists
ls components/content/Alert.vue4. Check component naming:
❌ ::alert → Component: alert.vue (lowercase doesn't auto-detect)
✅ ::Alert → Component: Alert.vue (PascalCase)
✅ ::alert → Component: Alert.vue + explicit registration---
Git Integration Issues
Error: Unable to commit changes
Symptom: "Failed to commit changes" error in Studio
Solutions:
1. Check repository permissions:
- User must have write access
- For GitHub: Check Settings → Collaborators
- For GitLab: Check Members → Add member with Developer+ role
2. Verify OAuth token has correct scopes:
# GitHub: Must have 'repo' scope
# GitLab: Must have 'write_repository' scope3. Check Git configuration:
export default defineNuxtConfig({
studio: {
git: {
enabled: true,
author: {
name: 'Studio CMS',
email: 'studio@yourdomain.com'
}
}
}
})4. Check branch protection rules:
- GitHub: Settings → Branches → Branch protection rules
- May prevent direct commits to main
- Solution: Allow Studio OAuth app to bypass rules or use different branch
---
Error: Merge conflicts
Symptom: "Merge conflict detected" when trying to save
Cause: Content changed externally while editing in Studio
Solutions:
1. Pull latest changes:
- Refresh Studio page to get latest content
- Re-apply your edits
2. Use different branches for Studio edits:
export default defineNuxtConfig({
studio: {
git: {
branch: 'studio-edits' // Separate branch
}
}
})3. Implement conflict resolution:
- Fetch latest from main
- Merge or rebase studio branch
- Resolve conflicts manually in Git
---
Performance Issues
Issue: Slow editor loading
Symptom: Studio takes >10 seconds to load editor
Solutions:
1. Reduce content size:
- Split large markdown files
- Optimize images (use WebP, compress)
- Archive old content
2. Optimize editor config:
export default defineNuxtConfig({
studio: {
editor: {
monaco: {
minimap: { enabled: false }, // Disable minimap
folding: false // Disable code folding
}
}
}
})3. Enable caching:
- Use Cloudflare caching for static assets
- Enable browser caching
4. Check network:
- Slow connection can delay loading
- Test on different network
---
Issue: Laggy typing in editor
Symptom: Delay between typing and characters appearing
Solutions:
1. Reduce file size:
- Files >5000 lines may cause lag
- Split into smaller files
2. Disable syntax highlighting for very large files:
export default defineNuxtConfig({
studio: {
editor: {
monaco: {
renderWhitespace: 'none',
folding: false
}
}
}
})3. Check CPU usage:
- Close other browser tabs
- Check for CPU-intensive browser extensions
---
Configuration Errors
Error: Invalid configuration in nuxt.config.ts
Symptom: Build fails with "Invalid Studio configuration"
Solutions:
1. Validate configuration structure:
export default defineNuxtConfig({
modules: ['@nuxt/content', '@nuxt/studio'],
studio: {
// Valid options only
editor: {
default: 'tiptap' // Must be 'tiptap' | 'monaco' | 'form'
}
}
})2. Check for typos:
❌ stuido: { ... }
✅ studio: { ... }
❌ editr: { ... }
✅ editor: { ... }3. Refer to schema:
- Check Studio docs for valid options
- Use TypeScript for autocomplete
---
Error: Environment variables not loading
Symptom: OAuth variables undefined at runtime
Solutions:
1. Check variable names:
# Must start with NUXT_
✅ NUXT_OAUTH_GITHUB_CLIENT_ID
❌ OAUTH_GITHUB_CLIENT_ID2. Verify variables set in correct environment:
- Cloudflare Pages: Check Production vs Preview
- Local: Check
.envfile exists and correct
3. Restart server after adding variables:
# Kill dev server and restart
npm run dev4. For Cloudflare Pages, redeploy after adding variables:
git commit --allow-empty -m "Trigger redeploy"
git push---
Getting Help
If none of these solutions work:
1. Check Studio GitHub Issues:
- https://github.com/nuxt-content/studio/issues
- Search for similar problems
2. Enable debug mode:
export default defineNuxtConfig({
studio: {
debug: true
}
})3. Collect diagnostics:
- Browser console errors
- Network tab errors
- Server logs
- Build logs from Cloudflare
4. Create minimal reproduction:
- Fresh Nuxt project
- Minimal Studio setup
- Reproduce the issue
5. Open GitHub issue with:
- Nuxt version
- Studio version
- Steps to reproduce
- Error logs
- Minimal reproduction repository
---
Preventive Measures
Before Deployment
- [ ] Test OAuth authentication locally
- [ ] Verify all environment variables set
- [ ] Test content editing and Git commits
- [ ] Check subdomain DNS configuration
- [ ] Validate SSL certificate
- [ ] Test in multiple browsers
Regular Maintenance
- [ ] Monitor OAuth token expiration
- [ ] Check for Studio updates monthly
- [ ] Review error logs weekly
- [ ] Test backup and restore procedures
- [ ] Document known issues and workarounds
Documentation
- [ ] Document deployment process
- [ ] Create troubleshooting guide for team
- [ ] Keep OAuth credentials secure and backed up
- [ ] Maintain list of team members with access
- [ ] Document custom configurations
---
Note: This troubleshooting guide covers most common issues. For platform-specific errors or advanced configurations, consult the official Nuxt Studio documentation and Cloudflare Pages documentation.
#!/bin/bash
# Nuxt Studio Prerequisites Checker
# Verifies system requirements and dependencies for Nuxt Studio setup
set -u -o pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Track overall status
ALL_CHECKS_PASSED=true
echo -e "${BLUE}==================================${NC}"
echo -e "${BLUE}Nuxt Studio Prerequisites Checker${NC}"
echo -e "${BLUE}==================================${NC}"
echo ""
# Function to print success message
success() {
echo -e "${GREEN}✓${NC} $1"
}
# Function to print error message
error() {
echo -e "${RED}✗${NC} $1"
ALL_CHECKS_PASSED=false
}
# Function to print warning message
warning() {
echo -e "${YELLOW}⚠${NC} $1"
}
# Function to print info message
info() {
echo -e "${BLUE}ℹ${NC} $1"
}
# Check Node.js version
echo "Checking Node.js..."
if command -v node &> /dev/null; then
NODE_VERSION=$(node -v | cut -d'v' -f2)
MAJOR_VERSION=$(echo $NODE_VERSION | cut -d'.' -f1)
if [ $MAJOR_VERSION -ge 18 ]; then
success "Node.js v$NODE_VERSION (>= 18.x required)"
else
error "Node.js v$NODE_VERSION found, but >= 18.x required"
info "Install latest Node.js from https://nodejs.org/"
fi
else
error "Node.js not found"
info "Install Node.js from https://nodejs.org/"
fi
echo ""
# Check package manager
echo "Checking package manager..."
if command -v npm &> /dev/null; then
NPM_VERSION=$(npm -v)
success "npm v$NPM_VERSION installed"
elif command -v bun &> /dev/null; then
BUN_VERSION=$(bun -v)
success "bun v$BUN_VERSION installed"
elif command -v pnpm &> /dev/null; then
PNPM_VERSION=$(pnpm -v)
success "pnpm v$PNPM_VERSION installed"
else
error "No package manager found (npm, bun, or pnpm)"
fi
echo ""
# Check if in Nuxt project
echo "Checking Nuxt project..."
if [ -f "package.json" ]; then
success "package.json found"
# Check for Nuxt dependency
if grep -q "\"nuxt\"" package.json; then
NUXT_VERSION=$(grep "\"nuxt\"" package.json | sed 's/.*": "//;s/".*//' | sed 's/[\^~]//g')
success "Nuxt dependency found (version: $NUXT_VERSION)"
# Check Nuxt version
MAJOR=$(echo $NUXT_VERSION | cut -d'.' -f1)
if [ "$MAJOR" -ge 3 ]; then
success "Nuxt version is >= 3.x (required for Studio)"
else
error "Nuxt version is < 3.x. Nuxt Studio requires Nuxt >= 3.x"
info "Upgrade Nuxt: npm install nuxt@latest"
fi
else
error "Nuxt dependency not found in package.json"
info "Install Nuxt: npx nuxi@latest init"
fi
else
error "package.json not found. Are you in a Nuxt project directory?"
fi
echo ""
# Check for @nuxt/content
echo "Checking @nuxt/content..."
if [ -f "package.json" ]; then
if grep -q "\"@nuxt/content\"" package.json; then
CONTENT_VERSION=$(grep "\"@nuxt/content\"" package.json | sed 's/.*": "//;s/".*//' | sed 's/[\^~]//g')
success "@nuxt/content found (version: $CONTENT_VERSION)"
# Check content version
MAJOR=$(echo $CONTENT_VERSION | cut -d'.' -f1)
if [ "$MAJOR" -ge 2 ]; then
success "@nuxt/content version is >= 2.x (required for Studio)"
else
error "@nuxt/content version is < 2.x. Studio requires >= 2.x"
info "Upgrade: npx nuxi@latest module add content"
fi
else
warning "@nuxt/content not found in package.json"
info "Install @nuxt/content: npx nuxi@latest module add content"
fi
fi
echo ""
# Check for @nuxt/studio
echo "Checking @nuxt/studio..."
if [ -f "package.json" ]; then
if grep -q "\"@nuxt/studio\"" package.json; then
STUDIO_VERSION=$(grep "\"@nuxt/studio\"" package.json | sed 's/.*": "//;s/".*//' | sed 's/[\^~]//g')
success "@nuxt/studio found (version: $STUDIO_VERSION)"
else
warning "@nuxt/studio not found in package.json"
info "Install @nuxt/studio: npx nuxi@latest module add nuxt-studio@beta"
fi
fi
echo ""
# Check nuxt.config.ts
echo "Checking nuxt.config.ts..."
if [ -f "nuxt.config.ts" ] || [ -f "nuxt.config.js" ]; then
CONFIG_FILE="nuxt.config.ts"
[ -f "nuxt.config.js" ] && CONFIG_FILE="nuxt.config.js"
success "$CONFIG_FILE found"
# Check if @nuxt/content is in modules
if grep -q "@nuxt/content" $CONFIG_FILE; then
success "@nuxt/content configured in modules"
else
warning "@nuxt/content not found in modules array"
info "Add '@nuxt/content' to modules array in $CONFIG_FILE"
fi
# Check if @nuxt/studio is in modules
if grep -q "@nuxt/studio" $CONFIG_FILE; then
success "@nuxt/studio configured in modules"
else
warning "@nuxt/studio not found in modules array"
info "Add '@nuxt/studio' to modules array in $CONFIG_FILE"
fi
else
error "nuxt.config.ts not found"
info "Create nuxt.config.ts in project root"
fi
echo ""
# Check content directory
echo "Checking content directory..."
if [ -d "content" ]; then
success "content/ directory exists"
# Count files in content directory
FILE_COUNT=$(find content -type f | wc -l | tr -d ' ')
if [ $FILE_COUNT -gt 0 ]; then
success "Found $FILE_COUNT file(s) in content/"
else
warning "content/ directory is empty"
info "Add some .md files to test Studio"
fi
else
warning "content/ directory not found"
info "Create content/ directory: mkdir content"
fi
echo ""
# Check Git
echo "Checking Git..."
if command -v git &> /dev/null; then
GIT_VERSION=$(git --version | cut -d' ' -f3)
success "Git v$GIT_VERSION installed"
# Check if in git repository
if git rev-parse --git-dir &> /dev/null; then
success "Git repository initialized"
# Check for remote
if git remote -v &> /dev/null 2>&1; then
REMOTE_COUNT=$(git remote | wc -l | tr -d ' ')
if [ $REMOTE_COUNT -gt 0 ]; then
success "Git remote configured"
else
warning "No Git remote configured"
info "Add remote for Studio Git integration"
fi
fi
else
warning "Not a Git repository"
info "Initialize Git: git init"
info "Studio requires Git for content persistence"
fi
else
error "Git not found"
info "Install Git from https://git-scm.com/"
info "Studio requires Git for content persistence"
fi
echo ""
# Check for OAuth environment variables (optional)
echo "Checking OAuth environment variables (optional)..."
ENV_FOUND=false
if [ -f ".env" ] || [ -f ".env.local" ]; then
ENV_FILE=".env"
[ -f ".env.local" ] && ENV_FILE=".env.local"
success "$ENV_FILE file found"
# Check for GitHub OAuth
if grep -q "NUXT_OAUTH_GITHUB_CLIENT_ID" $ENV_FILE; then
success "GitHub OAuth configured in $ENV_FILE"
ENV_FOUND=true
fi
# Check for GitLab OAuth
if grep -q "NUXT_OAUTH_GITLAB_CLIENT_ID" $ENV_FILE; then
success "GitLab OAuth configured in $ENV_FILE"
ENV_FOUND=true
fi
# Check for Google OAuth
if grep -q "NUXT_OAUTH_GOOGLE_CLIENT_ID" $ENV_FILE; then
success "Google OAuth configured in $ENV_FILE"
ENV_FOUND=true
fi
if [ "$ENV_FOUND" = false ]; then
warning "No OAuth providers configured in $ENV_FILE"
info "Configure OAuth for production deployment"
fi
else
info "No .env file found (optional for local development)"
info "Create .env for OAuth credentials"
fi
echo ""
echo -e "${BLUE}==================================${NC}"
# Final summary
if [ "$ALL_CHECKS_PASSED" = true ]; then
echo -e "${GREEN}✓ All required checks passed!${NC}"
echo ""
echo "Next steps:"
echo "1. Run: npm run dev"
echo "2. Visit: http://localhost:3000/_studio"
echo "3. Start editing content!"
exit 0
else
echo -e "${RED}✗ Some checks failed${NC}"
echo ""
echo "Please address the errors above before proceeding."
echo "Refer to references/troubleshooting.md for help."
exit 1
fi
#!/bin/bash
# Nuxt Studio OAuth Configuration Tester
# Tests OAuth environment variables setup
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
ISSUES_FOUND=false
echo -e "${BLUE}===================================${NC}"
echo -e "${BLUE}Nuxt Studio OAuth Configuration Tester${NC}"
echo -e "${BLUE}===================================${NC}"
echo ""
success() {
echo -e "${GREEN}✓${NC} $1"
}
error() {
echo -e "${RED}✗${NC} $1"
ISSUES_FOUND=true
}
warning() {
echo -e "${YELLOW}⚠${NC} $1"
}
info() {
echo -e "${BLUE}ℹ${NC} $1"
}
# Check for .env file
ENV_FILE=""
if [ -f ".env.local" ]; then
ENV_FILE=".env.local"
elif [ -f ".env" ]; then
ENV_FILE=".env"
fi
if [ -z "$ENV_FILE" ]; then
warning "No .env or .env.local file found"
info "For local testing, create .env.local with OAuth credentials"
echo ""
info "Testing environment variables from shell..."
echo ""
else
success "Found $ENV_FILE"
echo ""
# Source the env file with error handling
if [ -f "$ENV_FILE" ]; then
set -a
source "$ENV_FILE" || {
error "Failed to source $ENV_FILE"
exit 1
}
set +a
fi
fi
# Function to test OAuth provider
test_provider() {
local PROVIDER=$1
local CLIENT_ID_VAR=$2
local CLIENT_SECRET_VAR=$3
local SERVER_URL_VAR=$4
echo "Testing $PROVIDER OAuth..."
# Check CLIENT_ID
if [ ! -z "${!CLIENT_ID_VAR}" ]; then
# Mask the client ID for security (show first/last 4 chars)
MASKED_ID="${!CLIENT_ID_VAR:0:4}...${!CLIENT_ID_VAR: -4}"
success "$CLIENT_ID_VAR is set ($MASKED_ID)"
else
warning "$CLIENT_ID_VAR is not set"
info "Set $CLIENT_ID_VAR in $ENV_FILE or environment"
return
fi
# Check CLIENT_SECRET
if [ ! -z "${!CLIENT_SECRET_VAR}" ]; then
success "$CLIENT_SECRET_VAR is set (masked for security)"
# Basic validation: secret should be reasonably long
SECRET="${!CLIENT_SECRET_VAR}"
SECRET_LENGTH=${#SECRET}
if [ $SECRET_LENGTH -lt 20 ]; then
warning "$CLIENT_SECRET_VAR seems too short ($SECRET_LENGTH chars)"
info "OAuth secrets are typically 40+ characters"
fi
else
error "$CLIENT_SECRET_VAR is not set"
info "Set $CLIENT_SECRET_VAR in $ENV_FILE or environment"
return
fi
# Check server URL (for GitLab)
if [ ! -z "$SERVER_URL_VAR" ]; then
if [ ! -z "${!SERVER_URL_VAR}" ]; then
success "$SERVER_URL_VAR is set (${!SERVER_URL_VAR})"
# Validate URL format
if [[ ${!SERVER_URL_VAR} =~ ^https?:// ]]; then
success "Server URL format is valid"
else
error "Server URL should start with http:// or https://"
fi
fi
fi
echo ""
}
# Test GitHub OAuth
test_provider "GitHub" "NUXT_OAUTH_GITHUB_CLIENT_ID" "NUXT_OAUTH_GITHUB_CLIENT_SECRET"
# Test GitLab OAuth
test_provider "GitLab" "NUXT_OAUTH_GITLAB_CLIENT_ID" "NUXT_OAUTH_GITLAB_CLIENT_SECRET" "NUXT_OAUTH_GITLAB_SERVER_URL"
# Test Google OAuth
test_provider "Google" "NUXT_OAUTH_GOOGLE_CLIENT_ID" "NUXT_OAUTH_GOOGLE_CLIENT_SECRET"
# Check public Studio URL
echo "Checking public Studio URL..."
if [ ! -z "$NUXT_PUBLIC_STUDIO_URL" ]; then
success "NUXT_PUBLIC_STUDIO_URL is set ($NUXT_PUBLIC_STUDIO_URL)"
# Validate URL format
if [[ $NUXT_PUBLIC_STUDIO_URL =~ ^https?:// ]]; then
success "Studio URL format is valid"
# Check protocol
if [[ $NUXT_PUBLIC_STUDIO_URL =~ ^https:// ]]; then
success "Using HTTPS (recommended for production)"
else
warning "Using HTTP (only for local development)"
info "Use HTTPS for production deployments"
fi
else
error "Studio URL should start with http:// or https://"
fi
# Check for localhost
if [[ $NUXT_PUBLIC_STUDIO_URL =~ localhost ]]; then
info "Using localhost (development mode)"
else
info "Using production URL: $NUXT_PUBLIC_STUDIO_URL"
# Suggest subdomain check
if [[ ! $NUXT_PUBLIC_STUDIO_URL =~ studio\. ]] && [[ ! $NUXT_PUBLIC_STUDIO_URL =~ cms\. ]]; then
warning "URL doesn't use common Studio subdomain (studio. or cms.)"
info "Consider using studio.yourdomain.com for clarity"
fi
fi
else
warning "NUXT_PUBLIC_STUDIO_URL is not set"
info "Set to http://localhost:3000 for local development"
info "Set to https://studio.yourdomain.com for production"
fi
echo ""
# Summary and guidance
echo -e "${BLUE}===================================${NC}"
if [ "$ISSUES_FOUND" = true ]; then
echo -e "${RED}✗ Issues found with OAuth configuration${NC}"
echo ""
echo "Please address the issues above."
echo ""
echo "Quick fix:"
echo "1. Create .env.local file in project root"
echo "2. Add your OAuth credentials:"
echo ""
echo " NUXT_OAUTH_GITHUB_CLIENT_ID=your_client_id"
echo " NUXT_OAUTH_GITHUB_CLIENT_SECRET=your_client_secret"
echo " NUXT_PUBLIC_STUDIO_URL=http://localhost:3000"
echo ""
echo "3. Restart your dev server"
echo ""
echo "For detailed setup, see references/oauth-providers.md"
exit 1
else
PROVIDER_COUNT=0
[ ! -z "$NUXT_OAUTH_GITHUB_CLIENT_ID" ] && PROVIDER_COUNT=$((PROVIDER_COUNT + 1))
[ ! -z "$NUXT_OAUTH_GITLAB_CLIENT_ID" ] && PROVIDER_COUNT=$((PROVIDER_COUNT + 1))
[ ! -z "$NUXT_OAUTH_GOOGLE_CLIENT_ID" ] && PROVIDER_COUNT=$((PROVIDER_COUNT + 1))
if [ $PROVIDER_COUNT -eq 0 ]; then
echo -e "${YELLOW}⚠ No OAuth providers configured${NC}"
echo ""
echo "OAuth is required for production Studio deployment."
echo ""
echo "To set up OAuth:"
echo "1. Choose a provider (GitHub, GitLab, or Google)"
echo "2. Create an OAuth application"
echo "3. Set environment variables"
echo "4. Configure callback URLs"
echo ""
echo "See references/oauth-providers.md for detailed setup."
exit 0
else
echo -e "${GREEN}✓ OAuth configuration looks good!${NC}"
echo ""
echo "Configured providers: $PROVIDER_COUNT"
echo ""
echo "Next steps:"
echo "1. Verify OAuth callback URLs match deployment URL"
echo "2. Test authentication:"
echo " - Start dev server: npm run dev"
echo " - Visit: http://localhost:3000/_studio"
echo " - Click 'Sign in with [Provider]'"
echo "3. Check browser console for errors"
echo ""
echo "For production deployment:"
echo "- Set environment variables on deployment platform"
echo "- Update OAuth callback URLs to production URL"
echo "- Test authentication thoroughly"
exit 0
fi
fi
#!/bin/bash
# Nuxt Studio Configuration Validator
# Validates nuxt.config.ts for correct Studio setup
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
ALL_VALID=true
echo -e "${BLUE}===================================${NC}"
echo -e "${BLUE}Nuxt Studio Configuration Validator${NC}"
echo -e "${BLUE}===================================${NC}"
echo ""
success() {
echo -e "${GREEN}✓${NC} $1"
}
error() {
echo -e "${RED}✗${NC} $1"
ALL_VALID=false
}
warning() {
echo -e "${YELLOW}⚠${NC} $1"
}
info() {
echo -e "${BLUE}ℹ${NC} $1"
}
# Determine config file
CONFIG_FILE=""
if [ -f "nuxt.config.ts" ]; then
CONFIG_FILE="nuxt.config.ts"
elif [ -f "nuxt.config.js" ]; then
CONFIG_FILE="nuxt.config.js"
else
error "nuxt.config.ts or nuxt.config.js not found"
echo ""
info "Create nuxt.config.ts in project root"
exit 1
fi
success "Found $CONFIG_FILE"
echo ""
# Check modules array
echo "Checking modules configuration..."
if grep -q "modules:" "$CONFIG_FILE"; then
success "modules array found"
# Check @nuxt/content
if grep -A 20 "modules:" "$CONFIG_FILE" | grep -q "@nuxt/content"; then
success "@nuxt/content in modules"
else
error "@nuxt/content not in modules array"
info "Add '@nuxt/content' to modules"
fi
# Check @nuxt/studio
if grep -A 20 "modules:" "$CONFIG_FILE" | grep -q "@nuxt/studio"; then
success "@nuxt/studio in modules"
else
warning "@nuxt/studio not in modules array"
info "Add '@nuxt/studio' to modules"
fi
# Check module order (content should come before studio)
CONTENT_LINE=$(grep -n "@nuxt/content" "$CONFIG_FILE" | head -1 | cut -d':' -f1)
STUDIO_LINE=$(grep -n "@nuxt/studio" "$CONFIG_FILE" | head -1 | cut -d':' -f1)
if [ ! -z "$CONTENT_LINE" ] && [ ! -z "$STUDIO_LINE" ]; then
if [ $CONTENT_LINE -lt $STUDIO_LINE ]; then
success "Module order correct (@nuxt/content before @nuxt/studio)"
else
warning "@nuxt/content should come before @nuxt/studio in modules array"
fi
fi
else
error "modules array not found"
info "Add modules array to $CONFIG_FILE"
fi
echo ""
# Check Nitro preset for Cloudflare
echo "Checking Nitro configuration..."
if grep -q "nitro:" "$CONFIG_FILE"; then
success "nitro configuration found"
if grep -A 10 "nitro:" "$CONFIG_FILE" | grep -q "preset:"; then
PRESET=$(grep -A 10 "nitro:" "$CONFIG_FILE" | grep "preset:" | sed "s/.*preset:[ '\"]*//;s/['\",].*//")
if [ "$PRESET" = "cloudflare-pages" ] || [ "$PRESET" = "cloudflare" ]; then
success "Cloudflare preset configured: $PRESET"
else
warning "Nitro preset is '$PRESET' (not Cloudflare)"
info "For Cloudflare deployment, set preset to 'cloudflare-pages' or 'cloudflare'"
fi
else
warning "No nitro preset configured"
info "Set nitro.preset for deployment platform"
fi
else
warning "No nitro configuration found"
info "Add nitro config for deployment optimization"
fi
echo ""
# Check content configuration
echo "Checking content configuration..."
if grep -q "content:" "$CONFIG_FILE"; then
success "content configuration found"
# Check for experimental.clientDB (recommended for Studio)
if grep -A 20 "content:" "$CONFIG_FILE" | grep -q "clientDB"; then
success "experimental.clientDB configured (recommended for Studio)"
else
warning "experimental.clientDB not configured"
info "Add content.experimental.clientDB: true for MDC components in Studio"
fi
else
warning "No content configuration found (using defaults)"
info "Add content config for customization"
fi
echo ""
# Check studio configuration
echo "Checking studio configuration..."
if grep -q "studio:" "$CONFIG_FILE"; then
success "studio configuration found"
# Check editor config
if grep -A 20 "studio:" "$CONFIG_FILE" | grep -q "editor:"; then
success "editor configuration found"
# Check default editor
if grep -A 30 "studio:" "$CONFIG_FILE" | grep -q "default:"; then
DEFAULT_EDITOR=$(grep -A 30 "studio:" "$CONFIG_FILE" | grep "default:" | sed "s/.*default:[ '\"]*//;s/['\",].*//")
if [ "$DEFAULT_EDITOR" = "tiptap" ] || [ "$DEFAULT_EDITOR" = "monaco" ] || [ "$DEFAULT_EDITOR" = "form" ]; then
success "Valid default editor: $DEFAULT_EDITOR"
else
error "Invalid default editor: $DEFAULT_EDITOR"
info "Valid options: 'tiptap', 'monaco', 'form'"
fi
else
info "No default editor set (will use 'tiptap' by default)"
fi
else
info "No editor configuration (using Studio defaults)"
fi
# Check Git config
if grep -A 20 "studio:" "$CONFIG_FILE" | grep -q "git:"; then
success "git configuration found"
else
info "No git configuration (Studio will use defaults)"
fi
else
info "No studio configuration (using defaults)"
info "Add studio config for customization"
fi
echo ""
# Check runtime config for OAuth
echo "Checking runtime configuration..."
if grep -q "runtimeConfig:" "$CONFIG_FILE"; then
success "runtimeConfig found"
# Check for OAuth config
if grep -A 30 "runtimeConfig:" "$CONFIG_FILE" | grep -q "oauth:"; then
success "oauth configuration found"
# Check for GitHub
if grep -A 40 "runtimeConfig:" "$CONFIG_FILE" | grep -q "github:"; then
success "GitHub OAuth configured"
fi
# Check for GitLab
if grep -A 40 "runtimeConfig:" "$CONFIG_FILE" | grep -q "gitlab:"; then
success "GitLab OAuth configured"
fi
# Check for Google
if grep -A 40 "runtimeConfig:" "$CONFIG_FILE" | grep -q "google:"; then
success "Google OAuth configured"
fi
else
warning "No OAuth configuration found"
info "Add OAuth config for production authentication"
fi
# Check for public.studioUrl
if grep -A 30 "runtimeConfig:" "$CONFIG_FILE" | grep -q "studioUrl"; then
success "public.studioUrl configured"
else
warning "public.studioUrl not configured"
info "Add NUXT_PUBLIC_STUDIO_URL to runtimeConfig.public"
fi
else
warning "No runtimeConfig found"
info "Add runtimeConfig for OAuth and public variables"
fi
echo ""
# Check TypeScript strict mode (recommended)
echo "Checking TypeScript configuration..."
if grep -q "typescript:" "$CONFIG_FILE"; then
if grep -A 5 "typescript:" "$CONFIG_FILE" | grep -q "strict: true"; then
success "TypeScript strict mode enabled (recommended)"
else
info "TypeScript strict mode not enabled"
info "Enable for better type safety: typescript.strict: true"
fi
else
info "No TypeScript configuration (using defaults)"
fi
echo ""
echo -e "${BLUE}===================================${NC}"
# Final summary
if [ "$ALL_VALID" = true ]; then
echo -e "${GREEN}✓ Configuration validation passed!${NC}"
echo ""
echo "Your nuxt.config.ts is properly configured for Studio."
echo ""
echo "Optional improvements:"
echo "- Add OAuth configuration for production"
echo "- Configure editor preferences"
echo "- Set up Git author info"
exit 0
else
echo -e "${RED}✗ Configuration has errors${NC}"
echo ""
echo "Please fix the errors above."
echo "Refer to templates/nuxt.config.ts for a complete example."
exit 1
fi
// Nuxt Studio Configuration Template
// Copy and customize for your Nuxt Content + Studio project
export default defineNuxtConfig({
// Essential modules - order matters
modules: [
'@nuxt/content', // Required: Must be loaded before Studio
'@nuxt/studio' // Nuxt Studio module
],
// Nuxt Content configuration
content: {
// Enable experimental client DB for MDC components in Studio
experimental: {
clientDB: true
},
// Highlight code blocks
highlight: {
theme: 'github-dark',
preload: ['typescript', 'javascript', 'vue', 'css', 'bash']
},
// Markdown configuration
markdown: {
toc: {
depth: 3,
searchDepth: 3
}
}
},
// Studio configuration
studio: {
// Enable Studio
enabled: true,
// Editor configuration
editor: {
// Default editor: 'tiptap' | 'monaco' | 'form'
default: 'tiptap',
// Allow users to switch between editors
allowSwitching: true,
// Available editors for users
available: ['tiptap', 'monaco'],
// Monaco editor configuration
monaco: {
theme: 'vs-dark',
fontSize: 14,
wordWrap: 'on',
lineNumbers: 'on',
minimap: {
enabled: true
}
},
// TipTap editor configuration
tiptap: {
toolbar: {
enabled: true,
items: [
'bold',
'italic',
'strike',
'code',
'|',
'heading',
'|',
'bulletList',
'orderedList',
'|',
'link',
'image',
'|',
'codeBlock',
'blockquote'
]
},
// MDC component support
mdc: {
enabled: true,
components: ['Alert', 'CodeBlock', 'Card']
}
}
},
// Git configuration
git: {
enabled: true,
// Git author for commits made through Studio
author: {
name: 'Studio CMS',
email: 'studio@yourdomain.com'
},
// Branch for Studio edits (optional - defaults to current branch)
// branch: 'content-edits'
},
// Media library configuration
media: {
enabled: true,
// Storage backend: 'local' | 'cloudflare-r2' | 's3'
// Use 'cloudflare-r2' for Cloudflare deployments (required for Pages)
storage: 'cloudflare-r2',
// Cloudflare R2 configuration (required when using cloudflare-r2 storage)
r2: {
accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
bucketName: process.env.R2_BUCKET_NAME!,
publicUrl: process.env.R2_PUBLIC_URL!
},
// Supported file formats
formats: ['jpeg', 'png', 'gif', 'webp', 'avif', 'svg'],
// Max file size (10MB)
maxFileSize: 10 * 1024 * 1024,
// Thumbnail generation
thumbnails: {
enabled: true,
sizes: [
{ width: 200, height: 200, name: 'thumb' },
{ width: 800, height: 600, name: 'medium' }
]
}
}
},
// Nitro configuration for deployment
nitro: {
// Cloudflare Pages preset (for Cloudflare deployment)
preset: 'cloudflare-pages',
// Or use 'cloudflare' for Workers
// preset: 'cloudflare',
// Prerender routes for better performance
prerender: {
routes: ['/']
}
},
// Runtime configuration
runtimeConfig: {
// Private keys (server-side only)
oauth: {
github: {
clientId: process.env.NUXT_OAUTH_GITHUB_CLIENT_ID,
clientSecret: process.env.NUXT_OAUTH_GITHUB_CLIENT_SECRET
},
gitlab: {
clientId: process.env.NUXT_OAUTH_GITLAB_CLIENT_ID,
clientSecret: process.env.NUXT_OAUTH_GITLAB_CLIENT_SECRET,
serverUrl: process.env.NUXT_OAUTH_GITLAB_SERVER_URL
},
google: {
clientId: process.env.NUXT_OAUTH_GOOGLE_CLIENT_ID,
clientSecret: process.env.NUXT_OAUTH_GOOGLE_CLIENT_SECRET
}
},
// Public keys (exposed to client)
public: {
studioUrl: process.env.NUXT_PUBLIC_STUDIO_URL || 'http://localhost:3000'
}
},
// Development server configuration
devServer: {
port: 3000,
host: 'localhost'
},
// TypeScript configuration
typescript: {
strict: true,
shim: false
},
// Vite configuration
vite: {
optimizeDeps: {
include: ['@nuxt/content', '@nuxt/studio']
}
}
})
// GitHub OAuth Configuration for Nuxt Studio
// This is a reference template - Studio handles OAuth automatically
// Use this for understanding the OAuth flow or custom implementations
/**
* AUTOMATIC SETUP (Recommended):
*
* Studio automatically configures GitHub OAuth when you set environment variables:
*
* 1. Create GitHub OAuth App:
* - Go to: https://github.com/settings/developers
* - Click "New OAuth App"
* - Application name: "Your Site - Studio CMS"
* - Homepage URL: https://yourdomain.com
* - Authorization callback URL: https://studio.yourdomain.com/api/auth/callback/github
*
* 2. Set environment variables:
* NUXT_OAUTH_GITHUB_CLIENT_ID=your_client_id
* NUXT_OAUTH_GITHUB_CLIENT_SECRET=your_client_secret
*
* 3. Studio automatically handles the rest!
*/
// ============================================
// MANUAL CONFIGURATION (Advanced Use Cases)
// ============================================
import type { OAuthConfig } from 'nuxt-auth-utils'
export const githubOAuthConfig: OAuthConfig = {
// Provider name
provider: 'github',
// OAuth credentials from environment variables
clientId: process.env.NUXT_OAUTH_GITHUB_CLIENT_ID!,
clientSecret: process.env.NUXT_OAUTH_GITHUB_CLIENT_SECRET!,
// GitHub OAuth endpoints
authorize: {
url: 'https://github.com/login/oauth/authorize',
params: {
scope: 'read:user repo' // Required scopes for Studio
}
},
token: {
url: 'https://github.com/login/oauth/access_token',
params: {
grant_type: 'authorization_code'
}
},
// User info endpoint
userinfo: {
url: 'https://api.github.com/user'
},
// Callback URL (automatically constructed)
redirectUri: `${process.env.NUXT_PUBLIC_STUDIO_URL}/api/auth/callback/github`,
// Response type
responseType: 'code',
// Response mode
responseMode: 'query'
}
// ============================================
// OAUTH SCOPES EXPLAINED
// ============================================
/**
* Required scopes for Nuxt Studio with GitHub:
*
* - read:user
* Grants access to user profile information
* Used to identify the user in Studio
*
* - repo (for private repos) OR public_repo (for public repos only)
* Grants access to repository content
* Required for reading/writing content files
* Required for committing changes from Studio
*
* Optional scopes:
*
* - workflow (if you need to trigger GitHub Actions)
* Allows Studio to trigger workflows on commit
*/
// ============================================
// ENVIRONMENT SETUP
// ============================================
/**
* Local Development (.env.local):
*
* NUXT_OAUTH_GITHUB_CLIENT_ID=your_dev_client_id
* NUXT_OAUTH_GITHUB_CLIENT_SECRET=your_dev_secret
* NUXT_PUBLIC_STUDIO_URL=http://localhost:3000
*
* Important: Use a separate OAuth app for development with callback:
* http://localhost:3000/api/auth/callback/github
*/
/**
* Cloudflare Pages Production:
*
* Set in Workers & Pages → Settings → Environment variables:
*
* NUXT_OAUTH_GITHUB_CLIENT_ID=your_prod_client_id
* NUXT_OAUTH_GITHUB_CLIENT_SECRET=your_prod_secret
* NUXT_PUBLIC_STUDIO_URL=https://studio.yourdomain.com
*
* Important: Use production OAuth app with callback:
* https://studio.yourdomain.com/api/auth/callback/github
*/
/**
* Cloudflare Workers (via wrangler):
*
* Set secrets via CLI:
* wrangler secret put NUXT_OAUTH_GITHUB_CLIENT_ID
* wrangler secret put NUXT_OAUTH_GITHUB_CLIENT_SECRET
*
* Set public vars in wrangler.toml:
* [vars]
* NUXT_PUBLIC_STUDIO_URL = "https://studio.yourdomain.com"
*/
// ============================================
// TROUBLESHOOTING
// ============================================
/**
* Common GitHub OAuth Issues:
*
* 1. redirect_uri_mismatch
* - Verify callback URL in OAuth app matches deployment URL exactly
* - Check HTTPS vs HTTP
* - Check subdomain matches (studio.domain.com vs domain.com)
*
* 2. invalid_client
* - Verify CLIENT_ID and CLIENT_SECRET are correct
* - Check environment variables are set
* - Regenerate secret if lost
*
* 3. insufficient_scope
* - Ensure OAuth app has 'repo' scope (or 'public_repo')
* - Re-authorize the application
*
* 4. access_denied
* - User denied authorization
* - Check OAuth app is not suspended
* - Verify app has required permissions
*/
// ============================================
// TESTING OAUTH FLOW
// ============================================
/**
* Test GitHub OAuth locally:
*
* 1. Set up local environment variables
* 2. Start dev server: npm run dev
* 3. Visit: http://localhost:3000/_studio
* 4. Click "Sign in with GitHub"
* 5. Authorize the application
* 6. Should redirect back to Studio
*
* Check browser console and network tab for errors.
*/
// ============================================
// SECURITY BEST PRACTICES
// ============================================
/**
* 1. NEVER commit CLIENT_SECRET to Git
* - Use .env files (add to .gitignore)
* - Use environment variables on deployment platforms
*
* 2. Use different OAuth apps per environment
* - Development: localhost callback
* - Staging: staging.domain.com callback
* - Production: studio.domain.com callback
*
* 3. Rotate secrets regularly
* - Every 3-6 months minimum
* - Immediately if compromised
*
* 4. Limit OAuth app permissions
* - Use 'public_repo' instead of 'repo' if possible
* - Only request scopes you need
*
* 5. Monitor OAuth app usage
* - Check GitHub OAuth app settings for unusual activity
* - Review authorized users periodically
*/
// ============================================
// REFERENCE
// ============================================
/**
* GitHub OAuth Documentation:
* https://docs.github.com/en/developers/apps/building-oauth-apps
*
* Nuxt Studio OAuth Guide:
* https://content.nuxt.com/docs/studio/authentication
*
* Available Scopes:
* https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps
*/
export default githubOAuthConfig
// GitLab OAuth Configuration for Nuxt Studio
// This is a reference template - Studio handles OAuth automatically
/**
* AUTOMATIC SETUP (Recommended):
*
* Studio automatically configures GitLab OAuth when you set environment variables:
*
* 1. Create GitLab OAuth Application:
* - GitLab.com: https://gitlab.com/-/profile/applications
* - Self-hosted: https://your-gitlab.com/-/profile/applications
* - Name: "Your Site - Studio CMS"
* - Redirect URI: https://studio.yourdomain.com/api/auth/callback/gitlab
* - Confidential: ✅ Check this box
* - Scopes: read_user, read_repository, write_repository
*
* 2. Set environment variables:
* NUXT_OAUTH_GITLAB_CLIENT_ID=your_application_id
* NUXT_OAUTH_GITLAB_CLIENT_SECRET=your_secret
*
* 3. For self-hosted GitLab, also set:
* NUXT_OAUTH_GITLAB_SERVER_URL=https://your-gitlab.com
*
* 4. Studio automatically handles the rest!
*/
// ============================================
// MANUAL CONFIGURATION (Advanced)
// ============================================
import type { OAuthConfig } from 'nuxt-auth-utils'
export const gitlabOAuthConfig: OAuthConfig = {
// Provider name
provider: 'gitlab',
// OAuth credentials from environment variables
clientId: process.env.NUXT_OAUTH_GITLAB_CLIENT_ID!,
clientSecret: process.env.NUXT_OAUTH_GITLAB_CLIENT_SECRET!,
// GitLab server URL (defaults to GitLab.com)
serverUrl: process.env.NUXT_OAUTH_GITLAB_SERVER_URL || 'https://gitlab.com',
// GitLab OAuth endpoints
authorize: {
url: `${process.env.NUXT_OAUTH_GITLAB_SERVER_URL || 'https://gitlab.com'}/oauth/authorize`,
params: {
scope: 'read_user read_repository write_repository'
}
},
token: {
url: `${process.env.NUXT_OAUTH_GITLAB_SERVER_URL || 'https://gitlab.com'}/oauth/token`,
params: {
grant_type: 'authorization_code'
}
},
// User info endpoint
userinfo: {
url: `${process.env.NUXT_OAUTH_GITLAB_SERVER_URL || 'https://gitlab.com'}/api/v4/user`
},
// Callback URL
redirectUri: `${process.env.NUXT_PUBLIC_STUDIO_URL}/api/auth/callback/gitlab`,
// Response type
responseType: 'code',
// Response mode
responseMode: 'query'
}
// ============================================
// OAUTH SCOPES EXPLAINED
// ============================================
/**
* Required scopes for Nuxt Studio with GitLab:
*
* - read_user
* Grants access to user profile information
* Used to identify the user in Studio
*
* - read_repository
* Grants read access to repository content
* Required for reading content files
*
* - write_repository
* Grants write access to repository
* Required for committing changes from Studio
*
* Optional scopes:
*
* - api (full API access - NOT recommended, too broad)
* - read_api (read-only API access)
* - write_api (write API access)
*/
// ============================================
// SELF-HOSTED GITLAB SETUP
// ============================================
/**
* For self-hosted GitLab instances:
*
* 1. Ensure your GitLab instance is accessible from Studio deployment
* - Public internet access required
* - Or Studio must be on same network
*
* 2. Configure GitLab application settings:
* - Admin Area → Settings → General → Visibility and access controls
* - Enable "Allow requests to the local network from webhooks and integrations"
*
* 3. Set NUXT_OAUTH_GITLAB_SERVER_URL:
* NUXT_OAUTH_GITLAB_SERVER_URL=https://gitlab.yourcompany.com
*
* 4. Update OAuth redirect URI to match your GitLab URL:
* https://studio.yourdomain.com/api/auth/callback/gitlab
*/
// ============================================
// ENVIRONMENT SETUP
// ============================================
/**
* Local Development (.env.local):
*
* # GitLab.com
* NUXT_OAUTH_GITLAB_CLIENT_ID=your_dev_app_id
* NUXT_OAUTH_GITLAB_CLIENT_SECRET=your_dev_secret
* NUXT_PUBLIC_STUDIO_URL=http://localhost:3000
*
* # Self-hosted GitLab
* NUXT_OAUTH_GITLAB_CLIENT_ID=your_dev_app_id
* NUXT_OAUTH_GITLAB_CLIENT_SECRET=your_dev_secret
* NUXT_OAUTH_GITLAB_SERVER_URL=https://gitlab.yourcompany.com
* NUXT_PUBLIC_STUDIO_URL=http://localhost:3000
*
* Important: Create separate OAuth app for development with callback:
* http://localhost:3000/api/auth/callback/gitlab
*/
/**
* Cloudflare Pages Production:
*
* Set in Workers & Pages → Settings → Environment variables:
*
* NUXT_OAUTH_GITLAB_CLIENT_ID=your_prod_app_id
* NUXT_OAUTH_GITLAB_CLIENT_SECRET=your_prod_secret
* NUXT_OAUTH_GITLAB_SERVER_URL=https://gitlab.yourcompany.com (if self-hosted)
* NUXT_PUBLIC_STUDIO_URL=https://studio.yourdomain.com
*/
/**
* Cloudflare Workers (via wrangler):
*
* Set secrets via CLI:
* wrangler secret put NUXT_OAUTH_GITLAB_CLIENT_ID
* wrangler secret put NUXT_OAUTH_GITLAB_CLIENT_SECRET
*
* Set public vars in wrangler.toml:
* [vars]
* NUXT_OAUTH_GITLAB_SERVER_URL = "https://gitlab.yourcompany.com"
* NUXT_PUBLIC_STUDIO_URL = "https://studio.yourdomain.com"
*/
// ============================================
// TROUBLESHOOTING
// ============================================
/**
* Common GitLab OAuth Issues:
*
* 1. redirect_uri_mismatch
* - Verify redirect URI in OAuth app matches deployment URL
* - Check HTTPS vs HTTP
* - For self-hosted: Verify server URL is correct
*
* 2. invalid_client
* - Verify APPLICATION_ID and SECRET are correct
* - Check environment variables are set
* - Regenerate secret if lost
*
* 3. insufficient_scope
* - Ensure OAuth app has write_repository scope
* - Re-create application if scopes were changed
*
* 4. Self-hosted connection issues
* - Verify GitLab instance is accessible from Studio
* - Check firewall rules allow incoming connections
* - Verify SSL certificate is valid (or disable SSL verification for testing)
*
* 5. Confidential setting issues
* - Ensure "Confidential" checkbox is CHECKED when creating app
* - Non-confidential apps won't work with Studio
*/
// ============================================
// GITLAB.COM VS SELF-HOSTED
// ============================================
/**
* GitLab.com (SaaS):
* - Easier setup
* - No infrastructure maintenance
* - Public internet access always available
* - Standard OAuth endpoints
*
* Self-hosted GitLab:
* - Full control over instance
* - Can be on private network (but Studio must access it)
* - Requires NUXT_OAUTH_GITLAB_SERVER_URL configuration
* - May need additional firewall/network configuration
*
* Choose based on your team's GitLab hosting preference.
*/
// ============================================
// TESTING OAUTH FLOW
// ============================================
/**
* Test GitLab OAuth locally:
*
* 1. Set up local environment variables
* 2. Create development OAuth application in GitLab
* 3. Start dev server: npm run dev
* 4. Visit: http://localhost:3000/_studio
* 5. Click "Sign in with GitLab"
* 6. Authorize the application
* 7. Should redirect back to Studio
*
* Check browser console and network tab for errors.
* For self-hosted: Verify GitLab logs if authentication fails.
*/
// ============================================
// SECURITY BEST PRACTICES
// ============================================
/**
* 1. NEVER commit CLIENT_SECRET to Git
* - Use .env files (add to .gitignore)
* - Use environment variables on deployment
*
* 2. Always use Confidential applications
* - Non-confidential apps are less secure
* - Check "Confidential" when creating OAuth app
*
* 3. Use different OAuth apps per environment
* - Development: localhost callback
* - Staging: staging.domain.com callback
* - Production: studio.domain.com callback
*
* 4. For self-hosted GitLab:
* - Use HTTPS with valid SSL certificates
* - Restrict network access to trusted sources
* - Monitor OAuth application usage in GitLab admin
*
* 5. Rotate secrets regularly
* - Every 3-6 months minimum
* - Immediately if compromised
*/
// ============================================
// REFERENCE
// ============================================
/**
* GitLab OAuth Documentation:
* https://docs.gitlab.com/ee/integration/oauth_provider.html
*
* GitLab API Documentation:
* https://docs.gitlab.com/ee/api/
*
* Self-hosted GitLab Configuration:
* https://docs.gitlab.com/ee/administration/
*/
export default gitlabOAuthConfig
// Google OAuth Configuration for Nuxt Studio
// This is a reference template - Studio handles OAuth automatically
/**
* AUTOMATIC SETUP (Recommended):
*
* Studio automatically configures Google OAuth when you set environment variables:
*
* 1. Create Google Cloud Project and OAuth Client:
* - Go to: https://console.cloud.google.com/apis/credentials
* - Create project (or select existing)
* - Click "Create Credentials" → "OAuth client ID"
* - Configure OAuth consent screen (if first time)
* - Application type: "Web application"
* - Name: "Your Site - Studio CMS"
* - Authorized JavaScript origins: https://studio.yourdomain.com
* - Authorized redirect URIs: https://studio.yourdomain.com/api/auth/callback/google
*
* 2. Set environment variables:
* NUXT_OAUTH_GOOGLE_CLIENT_ID=your_client_id.apps.googleusercontent.com
* NUXT_OAUTH_GOOGLE_CLIENT_SECRET=your_client_secret
*
* 3. Studio automatically handles the rest!
*/
// ============================================
// MANUAL CONFIGURATION (Advanced)
// ============================================
import type { OAuthConfig } from 'nuxt-auth-utils'
export const googleOAuthConfig: OAuthConfig = {
// Provider name
provider: 'google',
// OAuth credentials from environment variables
clientId: process.env.NUXT_OAUTH_GOOGLE_CLIENT_ID!,
clientSecret: process.env.NUXT_OAUTH_GOOGLE_CLIENT_SECRET!,
// Google OAuth endpoints
authorize: {
url: 'https://accounts.google.com/o/oauth2/v2/auth',
params: {
scope: 'openid email profile',
access_type: 'offline', // For refresh tokens
prompt: 'consent' // Force consent screen to get refresh token
}
},
token: {
url: 'https://oauth2.googleapis.com/token',
params: {
grant_type: 'authorization_code'
}
},
// User info endpoint
userinfo: {
url: 'https://www.googleapis.com/oauth2/v2/userinfo'
},
// Callback URL
redirectUri: `${process.env.NUXT_PUBLIC_STUDIO_URL}/api/auth/callback/google`,
// Response type
responseType: 'code',
// Response mode
responseMode: 'query'
}
// ============================================
// OAUTH SCOPES EXPLAINED
// ============================================
/**
* Required scopes for Nuxt Studio with Google:
*
* - openid
* OpenID Connect authentication
* Required for user identification
*
* - email
* Access to user's email address
* Used to identify the user in Studio
*
* - profile
* Access to user's basic profile information
* Used for display name and avatar in Studio
*
* Optional scopes (for advanced integrations):
*
* - https://www.googleapis.com/auth/drive.file
* Access to Google Drive files (if storing content in Drive)
*
* - https://www.googleapis.com/auth/drive.readonly
* Read-only access to Google Drive
*
* Note: Google OAuth for Studio is typically used just for authentication,
* not for accessing Google services. Basic scopes are usually sufficient.
*/
// ============================================
// OAUTH CONSENT SCREEN SETUP
// ============================================
/**
* OAuth Consent Screen Configuration:
*
* 1. Go to: https://console.cloud.google.com/apis/credentials/consent
*
* 2. User Type:
* - Internal: For Google Workspace users only (recommended for teams)
* - External: For any Google account users
*
* 3. App Information:
* - App name: "Your Site Studio CMS"
* - User support email: your@email.com
* - App logo: (optional, but recommended)
*
* 4. Scopes:
* - Add: openid, email, profile
*
* 5. Test users (for External apps in testing):
* - Add email addresses of users who can test
* - Remove restriction when ready for production
*
* 6. Publishing Status:
* - Testing: Limited to test users (max 100)
* - In production: Available to all users
* - Publish when ready for team-wide use
*/
// ============================================
// ENVIRONMENT SETUP
// ============================================
/**
* Local Development (.env.local):
*
* NUXT_OAUTH_GOOGLE_CLIENT_ID=your_dev_client_id.apps.googleusercontent.com
* NUXT_OAUTH_GOOGLE_CLIENT_SECRET=your_dev_secret
* NUXT_PUBLIC_STUDIO_URL=http://localhost:3000
*
* Important: Create separate OAuth client for development with:
* Authorized redirect URI: http://localhost:3000/api/auth/callback/google
*/
/**
* Cloudflare Pages Production:
*
* Set in Workers & Pages → Settings → Environment variables:
*
* NUXT_OAUTH_GOOGLE_CLIENT_ID=your_prod_client_id.apps.googleusercontent.com
* NUXT_OAUTH_GOOGLE_CLIENT_SECRET=your_prod_secret
* NUXT_PUBLIC_STUDIO_URL=https://studio.yourdomain.com
*
* Important: Use production OAuth client with:
* Authorized redirect URI: https://studio.yourdomain.com/api/auth/callback/google
*/
/**
* Cloudflare Workers (via wrangler):
*
* Set secrets via CLI:
* wrangler secret put NUXT_OAUTH_GOOGLE_CLIENT_ID
* wrangler secret put NUXT_OAUTH_GOOGLE_CLIENT_SECRET
*
* Set public vars in wrangler.toml:
* [vars]
* NUXT_PUBLIC_STUDIO_URL = "https://studio.yourdomain.com"
*/
// ============================================
// TROUBLESHOOTING
// ============================================
/**
* Common Google OAuth Issues:
*
* 1. redirect_uri_mismatch
* - Verify redirect URI in OAuth client matches deployment URL exactly
* - Check HTTPS vs HTTP
* - Ensure subdomain matches (studio.domain.com vs domain.com)
* - Check for trailing slashes (should NOT have one)
*
* 2. invalid_client
* - Verify CLIENT_ID and CLIENT_SECRET are correct
* - Check environment variables are set
* - Regenerate secret if lost
*
* 3. access_denied
* - User denied authorization
* - App in "Testing" mode and user not in test users list
* - Consent screen not approved
*
* 4. App in testing mode restrictions
* - Max 100 test users in testing mode
* - Publish app to remove restriction
* - Or add users to test users list
*
* 5. Consent screen issues
* - Ensure consent screen is configured completely
* - Verify scopes are added
* - Check app is not suspended
*/
// ============================================
// AUTHORIZED DOMAINS
// ============================================
/**
* Configure authorized domains in Google Cloud Console:
*
* 1. OAuth consent screen → Authorized domains
* 2. Add your domain: yourdomain.com
* 3. Save changes
*
* This allows OAuth to work on any subdomain of yourdomain.com
* Example: studio.yourdomain.com, staging.yourdomain.com, etc.
*
* Note: Authorized JavaScript origins must still list each subdomain explicitly.
*/
// ============================================
// TESTING OAUTH FLOW
// ============================================
/**
* Test Google OAuth locally:
*
* 1. Set up local environment variables
* 2. Create development OAuth client in Google Cloud
* 3. Add test user (if app in testing mode)
* 4. Start dev server: npm run dev
* 5. Visit: http://localhost:3000/_studio
* 6. Click "Sign in with Google"
* 7. Choose Google account
* 8. Grant permissions
* 9. Should redirect back to Studio
*
* Check browser console and network tab for errors.
*/
// ============================================
// SECURITY BEST PRACTICES
// ============================================
/**
* 1. NEVER commit CLIENT_SECRET to Git
* - Use .env files (add to .gitignore)
* - Use environment variables on deployment platforms
*
* 2. Use different OAuth clients per environment
* - Development: localhost redirect
* - Staging: staging.domain.com redirect
* - Production: studio.domain.com redirect
*
* 3. Configure OAuth consent screen properly
* - Use Internal type for Google Workspace (more secure)
* - Use External type only if needed for non-workspace users
* - Publish app when ready for production
*
* 4. Rotate secrets regularly
* - Every 3-6 months minimum
* - Immediately if compromised
*
* 5. Monitor OAuth usage
* - Check Google Cloud Console for unusual activity
* - Review authorized users periodically
*
* 6. Restrict scopes
* - Only request scopes you need
* - Avoid broad scopes like drive.file unless necessary
*
* 7. Enable 2-factor authentication
* - For Google accounts with OAuth client access
* - Protects against account compromise
*/
// ============================================
// GOOGLE WORKSPACE INTEGRATION
// ============================================
/**
* For Google Workspace organizations:
*
* 1. Create OAuth client as "Internal" user type
* - Only Workspace users can authenticate
* - No need for app verification
* - More secure for team use
*
* 2. Admin can control app access
* - Workspace admin can enable/disable app
* - Can restrict to specific organizational units
*
* 3. No 100-user limit for testing
* - Internal apps don't have testing mode restrictions
* - All Workspace users have access immediately
*/
// ============================================
// REFERENCE
// ============================================
/**
* Google OAuth Documentation:
* https://developers.google.com/identity/protocols/oauth2
*
* OAuth Consent Screen Guide:
* https://support.google.com/cloud/answer/10311615
*
* Google Cloud Console:
* https://console.cloud.google.com/apis/credentials
*
* OAuth Playground (for testing):
* https://developers.google.com/oauthplayground/
*/
export default googleOAuthConfig