Skip to content

Commit 3e87891

Browse files
pedrobonaminjuice49rexxars
committed
feat(cli): add warning and docs for react-19 and Next.Js combined (#7660)
Co-authored-by: Ash <[email protected]> Co-authored-by: Espen Hovlandsdal <[email protected]>
1 parent f352db8 commit 3e87891

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

packages/@sanity/cli/src/actions/init-project/initProject.ts

+30-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import path from 'node:path'
44

55
import {type DatasetAclMode, type SanityProject} from '@sanity/client'
66
import {type Framework} from '@vercel/frameworks'
7+
import {type detectFrameworkRecord} from '@vercel/fs-detectors'
78
import dotenv from 'dotenv'
89
import execa, {type CommonOptions} from 'execa'
910
import {deburr, noop} from 'lodash'
1011
import pFilter from 'p-filter'
1112
import resolveFrom from 'resolve-from'
13+
import semver from 'semver'
1214
import {evaluate, patch} from 'silver-fleece'
1315
import which from 'which'
1416

@@ -55,6 +57,7 @@ import {
5557
promptForNextTemplate,
5658
promptForStudioPath,
5759
} from './prompts/nextjs'
60+
import {readPackageJson} from './readPackageJson'
5861
import {reconfigureV2Project} from './reconfigureV2Project'
5962
import templates from './templates'
6063
import {
@@ -110,7 +113,9 @@ export interface ProjectOrganization {
110113
// eslint-disable-next-line max-statements, complexity
111114
export default async function initSanity(
112115
args: CliCommandArguments<InitFlags>,
113-
context: CliCommandContext & {detectedFramework: Framework | null},
116+
context: CliCommandContext & {
117+
detectedFramework: Awaited<ReturnType<typeof detectFrameworkRecord>>
118+
},
114119
): Promise<void> {
115120
const {
116121
output,
@@ -128,6 +133,8 @@ export default async function initSanity(
128133
const cliFlags = args.extOptions
129134
const unattended = cliFlags.y || cliFlags.yes
130135
const print = unattended ? noop : output.print
136+
const warn = (msg: string) => output.warn(chalk.yellow.bgBlack(msg))
137+
131138
const intendedPlan = cliFlags['project-plan']
132139
const intendedCoupon = cliFlags.coupon
133140
const reconfigure = cliFlags.reconfigure
@@ -298,7 +305,8 @@ export default async function initSanity(
298305
}
299306

300307
let initNext = false
301-
if (detectedFramework?.slug === 'nextjs') {
308+
const isNextJs = detectedFramework?.slug === 'nextjs'
309+
if (isNextJs) {
302310
initNext = await prompt.single({
303311
type: 'confirm',
304312
message:
@@ -327,6 +335,26 @@ export default async function initSanity(
327335
// Ensure we are using the output path provided by user
328336
outputPath = answers.outputPath
329337

338+
if (isNextJs) {
339+
const packageJson = readPackageJson(`${outputPath}/package.json`)
340+
const reactVersion = packageJson?.dependencies?.react
341+
342+
if (reactVersion) {
343+
const isUsingReact19 = semver.coerce(reactVersion)?.major === 19
344+
const isUsingNextJs15 = semver.coerce(detectedFramework?.detectedVersion)?.major === 15
345+
346+
if (isUsingNextJs15 && isUsingReact19) {
347+
warn('╭────────────────────────────────────────────────────────────╮')
348+
warn('│ │')
349+
warn('│ It looks like you are using Next.js 15 and React 19 │')
350+
warn('│ Please read our compatibility guide. │')
351+
warn('│ https://www.sanity.io/help/react-19 │')
352+
warn('│ │')
353+
warn('╰────────────────────────────────────────────────────────────╯')
354+
}
355+
}
356+
}
357+
330358
if (initNext) {
331359
const useTypeScript = unattended ? true : await promptForTypeScript(prompt)
332360
trace.log({step: 'useTypeScript', selectedOption: useTypeScript ? 'yes' : 'no'})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import fs from 'node:fs'
2+
3+
import {type PackageJson} from '../../types'
4+
5+
/**
6+
* Read the `package.json` file at the given path
7+
*
8+
* @param filePath - Path to package.json to read
9+
* @returns The parsed package.json
10+
*/
11+
export function readPackageJson(filePath: string): PackageJson | undefined {
12+
try {
13+
// eslint-disable-next-line no-sync
14+
return JSON.parse(fs.readFileSync(filePath, 'utf8'))
15+
} catch (err) {
16+
return undefined
17+
}
18+
}

0 commit comments

Comments
 (0)