Skip to content

Conversation

@clementroche
Copy link
Member

@clementroche clementroche commented Dec 9, 2025

This commit is meant to make Sanity totally optional, meaning that anyone forking Satus can just build the project right away.
I create a branch beause i'm not entirely sure about the implementation, mostly the assertValue part. Instead of throwing error and stoppig the build, this will log an error.

@vercel
Copy link

vercel bot commented Dec 9, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
satus Ready Ready Preview Comment Dec 10, 2025 0:52am

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to make the Sanity CMS integration optional for the Satus project, allowing developers to fork and build without configuring Sanity. The implementation adds conditional logic to check if Sanity is configured and provides fallback implementations when it's not.

Key Changes:

  • Modified assertValue() to log errors instead of throwing, returning undefined for missing environment variables
  • Added conditional client creation using isSanityConfigured() check
  • Implemented fallback exports for sanityFetch, SanityLive, and draft mode routes when Sanity is not configured

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
integrations/sanity/env.ts Modified assertValue to return undefined and log errors instead of throwing exceptions
integrations/sanity/client.ts Made client creation conditional based on isSanityConfigured(), returning null when not configured
integrations/sanity/live/index.tsx Added fallback implementations for sanityFetch and SanityLive when client is null
integrations/sanity/fetch.ts Added null check for client before fetching, throwing error if not configured
app/api/draft-mode/enable/route.ts Made draft mode route conditional, returning 500 error response when Sanity not configured
app/sitemap.ts Added null check for imported client before using it to fetch sitemap data

Critical Issues Found: The implementation has several type safety and consistency issues that need to be addressed. The main concern is that assertValue() now returns undefined as T, which circumvents TypeScript's type system and can cause runtime errors. Additionally, there are inconsistencies in error handling patterns and missing parameter signatures in fallback functions.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +8 to +9
browserToken: publicToken,
serverToken: privateToken,
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When client is truthy but publicToken or privateToken are undefined (due to the modified assertValue function), defineLive will be called with undefined tokens. This could cause runtime errors or unexpected behavior in the Sanity live query functionality.

Consider adding explicit checks for required tokens:

client && publicToken && privateToken
  ? defineLive({...})
  : {...}

Copilot uses AI. Check for mistakes.
export const { GET } = defineEnableDraftMode({
client: client.withConfig({ token: privateToken }),
})
export const { GET } = client
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When client is truthy but privateToken is undefined (due to the modified assertValue function returning undefined), client.withConfig({ token: undefined }) will be called. This could cause issues with the draft mode functionality.

Consider checking for privateToken explicitly:

client && privateToken
  ? defineEnableDraftMode({
      client: client.withConfig({ token: privateToken }),
    })
  : {...}
Suggested change
export const { GET } = client
export const { GET } = client && privateToken

Copilot uses AI. Check for mistakes.
if (v === undefined) {
throw new Error(errorMessage)
console.error(errorMessage)
// throw new Error(errorMessage)
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented-out code should be removed rather than left in the codebase. If you're unsure about removing the error throwing behavior, consider using a feature flag or environment variable to control it instead.

Either remove this line or implement a proper configuration option.

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +32
if (!client) {
throw new Error('Sanity is not configured')
}
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling is inconsistent across the codebase. Here you throw an error, but in integrations/sanity/live/index.tsx:12-16 you return a resolved promise with an error object, and in app/api/draft-mode/enable/route.ts:11-15 you return a 500 response.

For consistency and better user experience, consider:

  1. Using the same error handling pattern across all fallback implementations
  2. Throwing errors early (like here) is good, but then the other fallbacks should also throw or handle errors consistently
  3. Document the expected behavior when Sanity is not configured

Copilot uses AI. Check for mistakes.
Comment on lines 38 to 40
console.error(errorMessage)
// throw new Error(errorMessage)
return undefined as T
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assertValue function is returning undefined as T which is a type-unsafe pattern that defeats the purpose of TypeScript's type system. This will cause runtime errors when the returned undefined values (like projectId, dataset, publicToken, studioUrl, previewURL) are used elsewhere in the code.

Instead of silencing the error and returning undefined as T, consider one of these safer approaches:

  1. Return a nullable type T | undefined and update call sites to handle null/undefined values
  2. Return a default empty string for string values (if appropriate for your use case)
  3. Keep throwing the error but make the client initialization conditional on isSanityConfigured() check first

Copilot uses AI. Check for mistakes.
Comment on lines 5 to 23
export const client = isSanityConfigured()
? createClient({
projectId,
dataset,
apiVersion,
useCdn: true,
perspective: 'published',
token: privateToken,
stega: {
studioUrl,
filter: (props) => {
if (props.sourcePath.at(-1) === 'title') {
return true
}

return props.filterDefault(props)
},
},
})
return props.filterDefault(props)
},
},
})
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When isSanityConfigured() returns true but environment variables are missing, createClient will be called with undefined values from the assertValue function in env.ts. This happens because assertValue now returns undefined as T instead of throwing an error.

This creates an inconsistency: isSanityConfigured() checks only for NEXT_PUBLIC_SANITY_PROJECT_ID and NEXT_PUBLIC_SANITY_DATASET, but createClient also requires publicToken, studioUrl, and previewURL which depend on other environment variables like NEXT_PUBLIC_SANITY_API_READ_TOKEN and NEXT_PUBLIC_BASE_URL.

Consider checking for all required environment variables in the conditional or handling undefined values more gracefully.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants