Form validation for email-gated viewing room in Next.js/Sanity

10 replies
Last updated: Nov 29, 2025
Hello, I’m looking at how to incorporate form validation into my Next JS / Sanity project, it’s for a ‘viewing room’ page — an online exhibition page that requires the visitor to submit their email address in order to view the page. There is no further authentication required and there is no login per se. Simply I need to be able to receive and store a submitted email address securely, and then allow access to the next page on receipt of a valid email address. Is it possible to get a response object from Sanity to confirm the submitted data perhaps? Would I be right to look at the next-auth sanity plugin (seems like it might be more for dealing with logged in users)? Very very grateful for any steering / tips.This is exactly an example of the type of use case:
https://whitecube.viewingrooms.com/viewing-room/introductions-sara-flores/
AI Update

For your viewing room use case, you're on the right track but don't need next-auth at all - that's designed for full authentication systems. Here's a simpler approach for your email-gate scenario:

Storing Email Submissions in Sanity

Yes, you can absolutely store submitted emails in Sanity and get a response confirming the submission. When you use the Sanity JavaScript client's create() mutation, you can use the returnDocuments parameter to get back the created document:

import { createClient } from '@sanity/client'

const client = createClient({
  projectId: 'your-project-id',
  dataset: 'your-dataset',
  token: 'your-write-token', // Keep this secret!
  apiVersion: '2025-02-19',
  useCdn: false
})

// In your Next.js API route
export async function POST(request) {
  const { email } = await request.json()
  
  try {
    const result = await client.create({
      _type: 'viewingRoomSubmission',
      email: email,
      submittedAt: new Date().toISOString(),
      viewingRoomId: 'your-viewing-room-id'
    }, { returnDocuments: true })
    
    // result will contain the created document with _id, _createdAt, etc.
    return Response.json({ 
      success: true, 
      submissionId: result._id 
    })
  } catch (error) {
    return Response.json({ success: false, error: error.message }, { status: 500 })
  }
}
  1. Create a schema in your Sanity Studio for storing submissions:
// schemas/viewingRoomSubmission.js
export default {
  name: 'viewingRoomSubmission',
  type: 'document',
  title: 'Viewing Room Submission',
  fields: [
    {
      name: 'email',
      type: 'string',
      validation: Rule => Rule.required().email()
    },
    {
      name: 'viewingRoomId',
      type: 'string'
    },
    {
      name: 'submittedAt',
      type: 'datetime'
    }
  ]
}
  1. Create a Next.js API route (/app/api/submit-email/route.js) to handle the submission securely with your write token (never expose this client-side!)

  2. Use session storage or cookies on the client side to track which viewing rooms the user has accessed

  3. Validate the email on both client and server side

Security Considerations

  • Keep your Sanity write token in environment variables, never in client code
  • Consider rate limiting your API route to prevent abuse
  • You might want to add a simple captcha to prevent bot submissions
  • Store the write token as SANITY_WRITE_TOKEN in your .env.local file

Response Object Details

When using returnDocuments: true with mutations, Sanity returns the full created document including:

  • _id: The unique document ID
  • _type: The document type
  • _createdAt: Timestamp of creation
  • _updatedAt: Timestamp of last update
  • All your custom fields (email, etc.)

According to the Sanity Mutations API documentation, you can also use returnIds: true if you only need the document IDs back rather than the full documents, which is more efficient.

This approach is much simpler than implementing full authentication and perfectly suited for your email-gated content use case! The client.create() method will return the created document when you pass the returnDocuments option, giving you confirmation that the email was successfully stored.

Show original thread
10 replies

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?