diff --git a/.changeset/fluffy-poems-ask.md b/.changeset/fluffy-poems-ask.md new file mode 100644 index 000000000..3b1826130 --- /dev/null +++ b/.changeset/fluffy-poems-ask.md @@ -0,0 +1,5 @@ +--- +"shadcn": patch +--- + +update handling of init urls diff --git a/apps/v4/app/(create)/init/route.ts b/apps/v4/app/(create)/init/route.ts index d704019e6..22c02af2f 100644 --- a/apps/v4/app/(create)/init/route.ts +++ b/apps/v4/app/(create)/init/route.ts @@ -44,10 +44,12 @@ export async function GET(request: NextRequest) { ) } - track("create_app", { - ...result.data, - preset: presetCode, - }) + if (searchParams.get("track") === "1") { + track("create_app", { + ...result.data, + preset: presetCode, + }) + } return NextResponse.json(parseResult.data) } catch (error) { diff --git a/packages/shadcn/src/commands/add.ts b/packages/shadcn/src/commands/add.ts index bfe30c165..5cd2511d6 100644 --- a/packages/shadcn/src/commands/add.ts +++ b/packages/shadcn/src/commands/add.ts @@ -187,8 +187,11 @@ export const add = new Command() }) // Resolve registry:base config. - const { registryBaseConfig, installStyleIndex } = - await resolveRegistryBaseConfig(initUrl, options.cwd) + const { + registryBaseConfig, + installStyleIndex, + url: cleanInitUrl, + } = await resolveRegistryBaseConfig(initUrl, options.cwd) config = await runInit({ cwd: options.cwd, @@ -201,7 +204,7 @@ export const add = new Command() cssVariables: true, rtl: false, installStyleIndex, - components: [initUrl, ...(options.components ?? [])], + components: [cleanInitUrl, ...(options.components ?? [])], registryBaseConfig, }) initHasRun = true @@ -228,8 +231,11 @@ export const add = new Command() base: selectedBase, template, }) - const { registryBaseConfig, installStyleIndex } = - await resolveRegistryBaseConfig(initUrl, options.cwd) + const { + registryBaseConfig, + installStyleIndex, + url: cleanInitUrl, + } = await resolveRegistryBaseConfig(initUrl, options.cwd) config = await runInit({ cwd: options.cwd, @@ -242,7 +248,7 @@ export const add = new Command() cssVariables: true, rtl: false, installStyleIndex, - components: [initUrl, ...(options.components ?? [])], + components: [cleanInitUrl, ...(options.components ?? [])], registryBaseConfig, }) initHasRun = true diff --git a/packages/shadcn/src/commands/init.ts b/packages/shadcn/src/commands/init.ts index d762c6df9..9fa9446fa 100644 --- a/packages/shadcn/src/commands/init.ts +++ b/packages/shadcn/src/commands/init.ts @@ -384,6 +384,9 @@ export const init = new Command() } else if (options.rtl === false) { url.searchParams.delete("rtl") } + if (url.pathname === "/init" && presetArg.startsWith(SHADCN_URL)) { + url.searchParams.set("track", "1") + } initUrl = url.toString() presetBase = url.searchParams.get("base") ?? undefined } else if (isPresetCode(presetArg)) { @@ -512,12 +515,18 @@ export const init = new Command() } // Resolve registry:base config from the first component. - const { registryBaseConfig, installStyleIndex } = - await resolveRegistryBaseConfig(components[0], cwd, { - registries: existingConfig?.registries as - | z.infer - | undefined, - }) + const { + registryBaseConfig, + installStyleIndex, + url: cleanUrl, + } = await resolveRegistryBaseConfig(components[0], cwd, { + registries: existingConfig?.registries as + | z.infer + | undefined, + }) + + // Use the clean URL (track param stripped) for subsequent fetches. + components[0] = cleanUrl if (!installStyleIndex) { options.installStyleIndex = false diff --git a/packages/shadcn/src/preset/presets.ts b/packages/shadcn/src/preset/presets.ts index a0394d39a..8c469d29b 100644 --- a/packages/shadcn/src/preset/presets.ts +++ b/packages/shadcn/src/preset/presets.ts @@ -3,6 +3,7 @@ import { buildUrlAndHeadersForRegistryItem } from "@/src/registry/builder" import { configWithDefaults } from "@/src/registry/config" import { REGISTRY_URL, SHADCN_URL } from "@/src/registry/constants" import { type registryConfigSchema } from "@/src/registry/schema" +import { isUrl } from "@/src/registry/utils" import { createConfig } from "@/src/utils/get-config" import { highlighter } from "@/src/utils/highlighter" import { logger } from "@/src/utils/logger" @@ -141,6 +142,9 @@ export function resolveInitUrl( params.set("template", options.template) } + // Signal the server to record this init run. + params.set("track", "1") + return `${SHADCN_URL}/init?${params.toString()}` } @@ -272,8 +276,25 @@ export async function resolveRegistryBaseConfig( const registryBaseConfig = item?.type === "registry:base" && item.config ? item.config : undefined + // Strip the track param so subsequent fetches don't re-trigger tracking. + let cleanUrl = initUrl + if (isShadcnInitUrl(initUrl)) { + const url = new URL(initUrl) + url.searchParams.delete("track") + cleanUrl = url.toString() + } + return { registryBaseConfig, installStyleIndex: item?.extends !== "none", + url: cleanUrl, + } +} + +function isShadcnInitUrl(url: string) { + try { + return new URL(url).pathname === "/init" && url.startsWith(SHADCN_URL) + } catch { + return false } }