mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-26 22:26:05 +00:00
feat: use REGISTRY_URL
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import * as fs from "fs/promises"
|
||||
import * as path from "path"
|
||||
import { preFlightBuild } from "@/src/preflights/preflight-build"
|
||||
import { SHADCN_URL } from "@/src/registry/constants"
|
||||
import { registryItemSchema, registrySchema } from "@/src/schema"
|
||||
import { handleError } from "@/src/utils/handle-error"
|
||||
import { highlighter } from "@/src/utils/highlighter"
|
||||
@@ -57,7 +58,7 @@ export const build = new Command()
|
||||
|
||||
// Add the schema to the registry item.
|
||||
registryItem["$schema"] =
|
||||
"https://ui.shadcn.com/schema/registry-item.json"
|
||||
`${SHADCN_URL}/schema/registry-item.json`
|
||||
|
||||
// Loop through each file in the files array.
|
||||
for (const file of registryItem.files ?? []) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { existsSync } from "fs"
|
||||
import path from "path"
|
||||
import { SHADCN_URL } from "@/src/registry/constants"
|
||||
import { getBase, getConfig } from "@/src/utils/get-config"
|
||||
import {
|
||||
formatMonorepoMessage,
|
||||
@@ -143,11 +144,11 @@ function collectInfo(
|
||||
: null,
|
||||
components,
|
||||
links: {
|
||||
docs: "https://ui.shadcn.com/docs",
|
||||
components: `https://ui.shadcn.com/docs/components/${base}/[component].md`,
|
||||
docs: `${SHADCN_URL}/docs`,
|
||||
components: `${SHADCN_URL}/docs/components/${base}/[component].md`,
|
||||
ui: `${GITHUB_RAW_BASE}/${base}/ui/[component].tsx`,
|
||||
examples: `${GITHUB_RAW_BASE}/${base}/examples/[component]-example.tsx`,
|
||||
schema: "https://ui.shadcn.com/schema.json",
|
||||
schema: `${SHADCN_URL}/schema.json`,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
resolveRegistryBaseConfig,
|
||||
} from "@/src/preset/presets"
|
||||
import { getRegistryBaseColors, getRegistryStyles } from "@/src/registry/api"
|
||||
import { BUILTIN_REGISTRIES } from "@/src/registry/constants"
|
||||
import { BUILTIN_REGISTRIES, SHADCN_URL } from "@/src/registry/constants"
|
||||
import { clearRegistryContext } from "@/src/registry/context"
|
||||
import { registryConfigSchema } from "@/src/registry/schema"
|
||||
import { isUrl } from "@/src/registry/utils"
|
||||
@@ -317,7 +317,7 @@ export const init = new Command()
|
||||
)
|
||||
logger.log(
|
||||
` See ${highlighter.info(
|
||||
"https://ui.shadcn.com/docs/installation/laravel"
|
||||
`${SHADCN_URL}/docs/installation/laravel`
|
||||
)} for more information.`
|
||||
)
|
||||
logger.break()
|
||||
@@ -813,7 +813,7 @@ async function promptForConfig(defaultConfig: Config | null = null) {
|
||||
}
|
||||
|
||||
return rawConfigSchema.parse({
|
||||
$schema: "https://ui.shadcn.com/schema.json",
|
||||
$schema: `${SHADCN_URL}/schema.json`,
|
||||
style: options.style,
|
||||
tailwind: {
|
||||
config: options.tailwindConfig,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as fs from "fs/promises"
|
||||
import * as path from "path"
|
||||
import { preFlightRegistryBuild } from "@/src/preflights/preflight-registry"
|
||||
import { SHADCN_URL } from "@/src/registry/constants"
|
||||
import { recursivelyResolveFileImports } from "@/src/registry/utils"
|
||||
import { configSchema, registryItemSchema, registrySchema } from "@/src/schema"
|
||||
import * as ERRORS from "@/src/utils/errors"
|
||||
@@ -121,7 +122,7 @@ async function buildRegistry(opts: z.infer<typeof buildOptionsSchema>) {
|
||||
|
||||
// Add the schema to the registry item.
|
||||
registryItem["$schema"] =
|
||||
"https://ui.shadcn.com/schema/registry-item.json"
|
||||
`${SHADCN_URL}/schema/registry-item.json`
|
||||
|
||||
for (const file of registryItem.files) {
|
||||
const absPath = path.resolve(resolvePaths.cwd, file.path)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { promises as fs } from "fs"
|
||||
import path from "path"
|
||||
import { SHADCN_URL } from "@/src/registry/constants"
|
||||
import { Config } from "@/src/utils/get-config"
|
||||
import { highlighter } from "@/src/utils/highlighter"
|
||||
import { logger } from "@/src/utils/logger"
|
||||
@@ -15,7 +16,7 @@ const FILES_NEEDING_MANUAL_REVIEW = [
|
||||
"calendar.tsx",
|
||||
]
|
||||
|
||||
const RTL_DOCS_URL = "https://ui.shadcn.com/docs/rtl#manual-migration-optional"
|
||||
const RTL_DOCS_URL = `${SHADCN_URL}/docs/rtl#manual-migration-optional`
|
||||
|
||||
export async function migrateRtl(
|
||||
config: Config,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import path from "path"
|
||||
import { addOptionsSchema } from "@/src/commands/add"
|
||||
import { SHADCN_URL } from "@/src/registry/constants"
|
||||
import * as ERRORS from "@/src/utils/errors"
|
||||
import { getConfig } from "@/src/utils/get-config"
|
||||
import {
|
||||
@@ -66,7 +67,7 @@ export async function preFlightAdd(options: z.infer<typeof addOptionsSchema>) {
|
||||
)
|
||||
logger.error(
|
||||
`Learn more at ${highlighter.info(
|
||||
"https://ui.shadcn.com/docs/components-json"
|
||||
`${SHADCN_URL}/docs/components-json`
|
||||
)}.`
|
||||
)
|
||||
logger.break()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import path from "path"
|
||||
import { addOptionsSchema } from "@/src/commands/add"
|
||||
import { migrateOptionsSchema } from "@/src/commands/migrate"
|
||||
import { SHADCN_URL } from "@/src/registry/constants"
|
||||
import * as ERRORS from "@/src/utils/errors"
|
||||
import { getConfig } from "@/src/utils/get-config"
|
||||
import { highlighter } from "@/src/utils/highlighter"
|
||||
@@ -55,7 +56,7 @@ export async function preFlightMigrate(
|
||||
)
|
||||
logger.error(
|
||||
`Learn more at ${highlighter.info(
|
||||
"https://ui.shadcn.com/docs/components-json"
|
||||
`${SHADCN_URL}/docs/components-json`
|
||||
)}.`
|
||||
)
|
||||
logger.break()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { getRegistryItems } from "@/src/registry/api"
|
||||
import { buildUrlAndHeadersForRegistryItem } from "@/src/registry/builder"
|
||||
import { configWithDefaults } from "@/src/registry/config"
|
||||
import { REGISTRY_URL } from "@/src/registry/constants"
|
||||
import { REGISTRY_URL, SHADCN_URL } from "@/src/registry/constants"
|
||||
import { type registryConfigSchema } from "@/src/registry/schema"
|
||||
import { createConfig } from "@/src/utils/get-config"
|
||||
import { highlighter } from "@/src/utils/highlighter"
|
||||
@@ -11,8 +11,6 @@ import open from "open"
|
||||
import prompts from "prompts"
|
||||
import { type z } from "zod"
|
||||
|
||||
const SHADCN_URL = REGISTRY_URL.replace(/\/r\/?$/, "")
|
||||
|
||||
export const DEFAULT_PRESETS = {
|
||||
nova: {
|
||||
title: "Nova",
|
||||
@@ -174,7 +172,7 @@ export async function promptForPreset(options: {
|
||||
})),
|
||||
{
|
||||
title: "Custom",
|
||||
description: "Build your own on https://ui.shadcn.com/create",
|
||||
description: `Build your own at ${highlighter.info(`${SHADCN_URL}/create`)}`,
|
||||
value: "custom",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -4,6 +4,8 @@ import { z } from "zod"
|
||||
export const REGISTRY_URL =
|
||||
process.env.REGISTRY_URL ?? "https://ui.shadcn.com/r"
|
||||
|
||||
export const SHADCN_URL = REGISTRY_URL.replace(/\/r\/?$/, "")
|
||||
|
||||
export const FALLBACK_STYLE = "new-york-v4"
|
||||
|
||||
export const BASE_COLORS = [
|
||||
@@ -11,10 +13,6 @@ export const BASE_COLORS = [
|
||||
name: "neutral",
|
||||
label: "Neutral",
|
||||
},
|
||||
{
|
||||
name: "gray",
|
||||
label: "Gray",
|
||||
},
|
||||
{
|
||||
name: "zinc",
|
||||
label: "Zinc",
|
||||
@@ -24,8 +22,20 @@ export const BASE_COLORS = [
|
||||
label: "Stone",
|
||||
},
|
||||
{
|
||||
name: "slate",
|
||||
label: "Slate",
|
||||
name: "mauve",
|
||||
label: "Mauve",
|
||||
},
|
||||
{
|
||||
name: "olive",
|
||||
label: "Olive",
|
||||
},
|
||||
{
|
||||
name: "mist",
|
||||
label: "Mist",
|
||||
},
|
||||
{
|
||||
name: "taupe",
|
||||
label: "Taupe",
|
||||
},
|
||||
] as const
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SHADCN_URL } from "@/src/registry/constants"
|
||||
import { z } from "zod"
|
||||
|
||||
// Error codes for programmatic error handling
|
||||
@@ -245,7 +246,7 @@ export class RegistryParseError extends RegistryError {
|
||||
cause: parseError,
|
||||
context: { item },
|
||||
suggestion:
|
||||
"The registry item may be corrupted or have an invalid format. Please make sure it returns a valid JSON object. See https://ui.shadcn.com/schema/registry-item.json.",
|
||||
`The registry item may be corrupted or have an invalid format. Please make sure it returns a valid JSON object. See ${SHADCN_URL}/schema/registry-item.json.`,
|
||||
})
|
||||
|
||||
this.parseError = parseError
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SHADCN_URL } from "@/src/registry/constants"
|
||||
import { highlighter } from "@/src/utils/highlighter"
|
||||
import { logger } from "@/src/utils/logger"
|
||||
|
||||
@@ -19,7 +20,7 @@ export const laravel = createTemplate({
|
||||
)
|
||||
logger.log(
|
||||
` See ${highlighter.info(
|
||||
"https://ui.shadcn.com/docs/installation/laravel"
|
||||
`${SHADCN_URL}/docs/installation/laravel`
|
||||
)} for more information.`
|
||||
)
|
||||
logger.break()
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { SHADCN_URL } from "@/src/registry/constants"
|
||||
|
||||
export const FRAMEWORKS = {
|
||||
"next-app": {
|
||||
name: "next-app",
|
||||
label: "Next.js",
|
||||
links: {
|
||||
installation: "https://ui.shadcn.com/docs/installation/next",
|
||||
installation: `${SHADCN_URL}/docs/installation/next`,
|
||||
tailwind: "https://tailwindcss.com/docs/guides/nextjs",
|
||||
},
|
||||
},
|
||||
@@ -11,7 +13,7 @@ export const FRAMEWORKS = {
|
||||
name: "next-pages",
|
||||
label: "Next.js",
|
||||
links: {
|
||||
installation: "https://ui.shadcn.com/docs/installation/next",
|
||||
installation: `${SHADCN_URL}/docs/installation/next`,
|
||||
tailwind: "https://tailwindcss.com/docs/guides/nextjs",
|
||||
},
|
||||
},
|
||||
@@ -19,7 +21,7 @@ export const FRAMEWORKS = {
|
||||
name: "remix",
|
||||
label: "Remix",
|
||||
links: {
|
||||
installation: "https://ui.shadcn.com/docs/installation/remix",
|
||||
installation: `${SHADCN_URL}/docs/installation/remix`,
|
||||
tailwind: "https://tailwindcss.com/docs/guides/remix",
|
||||
},
|
||||
},
|
||||
@@ -27,7 +29,7 @@ export const FRAMEWORKS = {
|
||||
name: "react-router",
|
||||
label: "React Router",
|
||||
links: {
|
||||
installation: "https://ui.shadcn.com/docs/installation/react-router",
|
||||
installation: `${SHADCN_URL}/docs/installation/react-router`,
|
||||
tailwind:
|
||||
"https://tailwindcss.com/docs/installation/framework-guides/react-router",
|
||||
},
|
||||
@@ -36,7 +38,7 @@ export const FRAMEWORKS = {
|
||||
name: "vite",
|
||||
label: "Vite",
|
||||
links: {
|
||||
installation: "https://ui.shadcn.com/docs/installation/vite",
|
||||
installation: `${SHADCN_URL}/docs/installation/vite`,
|
||||
tailwind: "https://tailwindcss.com/docs/guides/vite",
|
||||
},
|
||||
},
|
||||
@@ -44,7 +46,7 @@ export const FRAMEWORKS = {
|
||||
name: "astro",
|
||||
label: "Astro",
|
||||
links: {
|
||||
installation: "https://ui.shadcn.com/docs/installation/astro",
|
||||
installation: `${SHADCN_URL}/docs/installation/astro`,
|
||||
tailwind: "https://tailwindcss.com/docs/guides/astro",
|
||||
},
|
||||
},
|
||||
@@ -52,7 +54,7 @@ export const FRAMEWORKS = {
|
||||
name: "laravel",
|
||||
label: "Laravel",
|
||||
links: {
|
||||
installation: "https://ui.shadcn.com/docs/installation/laravel",
|
||||
installation: `${SHADCN_URL}/docs/installation/laravel`,
|
||||
tailwind: "https://tailwindcss.com/docs/guides/laravel",
|
||||
},
|
||||
},
|
||||
@@ -60,7 +62,7 @@ export const FRAMEWORKS = {
|
||||
name: "tanstack-start",
|
||||
label: "TanStack Start",
|
||||
links: {
|
||||
installation: "https://ui.shadcn.com/docs/installation/tanstack",
|
||||
installation: `${SHADCN_URL}/docs/installation/tanstack`,
|
||||
tailwind: "https://tailwindcss.com/docs/installation/using-postcss",
|
||||
},
|
||||
},
|
||||
@@ -68,7 +70,7 @@ export const FRAMEWORKS = {
|
||||
name: "gatsby",
|
||||
label: "Gatsby",
|
||||
links: {
|
||||
installation: "https://ui.shadcn.com/docs/installation/gatsby",
|
||||
installation: `${SHADCN_URL}/docs/installation/gatsby`,
|
||||
tailwind: "https://tailwindcss.com/docs/guides/gatsby",
|
||||
},
|
||||
},
|
||||
@@ -76,7 +78,7 @@ export const FRAMEWORKS = {
|
||||
name: "expo",
|
||||
label: "Expo",
|
||||
links: {
|
||||
installation: "https://ui.shadcn.com/docs/installation/expo",
|
||||
installation: `${SHADCN_URL}/docs/installation/expo`,
|
||||
tailwind: "https://www.nativewind.dev/docs/getting-started/installation",
|
||||
},
|
||||
},
|
||||
@@ -84,7 +86,7 @@ export const FRAMEWORKS = {
|
||||
name: "manual",
|
||||
label: "Manual",
|
||||
links: {
|
||||
installation: "https://ui.shadcn.com/docs/installation/manual",
|
||||
installation: `${SHADCN_URL}/docs/installation/manual`,
|
||||
tailwind: "https://tailwindcss.com/docs/installation",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { promises as fsPromises } from "fs"
|
||||
import path from "path"
|
||||
import { getShadcnRegistryIndex } from "@/src/registry/api"
|
||||
import { SHADCN_URL } from "@/src/registry/constants"
|
||||
import { rawConfigSchema } from "@/src/schema"
|
||||
import { Framework, FRAMEWORKS } from "@/src/utils/frameworks"
|
||||
import { Config, getConfig, resolveConfigPaths } from "@/src/utils/get-config"
|
||||
@@ -384,7 +385,7 @@ export async function getProjectConfig(
|
||||
}
|
||||
|
||||
const config: z.infer<typeof rawConfigSchema> = {
|
||||
$schema: "https://ui.shadcn.com/schema.json",
|
||||
$schema: `${SHADCN_URL}/schema.json`,
|
||||
rsc: projectInfo.isRSC,
|
||||
tsx: projectInfo.isTsx,
|
||||
style: "new-york",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SHADCN_URL } from "@/src/registry/constants"
|
||||
import { RegistryItem } from "@/src/schema"
|
||||
import { Config } from "@/src/utils/get-config"
|
||||
import { getPackageInfo } from "@/src/utils/get-package-info"
|
||||
@@ -40,7 +41,7 @@ export async function updateDependencies(
|
||||
} else {
|
||||
dependenciesSpinner.stopAndPersist()
|
||||
logger.warn(
|
||||
"\nIt looks like you are using React 19. \nSome packages may fail to install due to peer dependency issues in npm (see https://ui.shadcn.com/react-19).\n"
|
||||
`\nIt looks like you are using React 19. \nSome packages may fail to install due to peer dependency issues in npm (see ${SHADCN_URL}/react-19).\n`
|
||||
)
|
||||
const confirmation = await prompts([
|
||||
{
|
||||
|
||||
@@ -92,14 +92,16 @@ npx shadcn@latest docs button dialog select
|
||||
## Workflow
|
||||
|
||||
1. **Get project context** — already injected above. Run `npx shadcn@latest info` again if you need to refresh.
|
||||
2. **Check installed components** — look in the `resolvedPaths.ui` directory before importing or adding. Don't import components that haven't been added, and don't re-add ones already installed.
|
||||
2. **Check installed components first** — before running `add`, always check the `components` list from project context or list the `resolvedPaths.ui` directory. Don't import components that haven't been added, and don't re-add ones already installed.
|
||||
3. **Find components** — `npx shadcn@latest search`.
|
||||
4. **Get docs and examples** — run `npx shadcn@latest docs <component>` to get URLs, then fetch them. Use `npx shadcn@latest view` to browse registry items you haven't installed. To preview changes to installed components, use `npx shadcn@latest add --diff`.
|
||||
5. **Install or update** — `npx shadcn@latest add`. When updating existing components, use `--dry-run` and `--diff` to preview changes first (see [Updating Components](#updating-components) below).
|
||||
6. **Fix imports in third-party components** — After adding components from community registries (e.g. `@bundui`, `@magicui`), check the added non-UI files for hardcoded import paths like `@/components/ui/...`. These won't match the project's actual aliases. Use `npx shadcn@latest info` to get the correct `ui` alias (e.g. `@workspace/ui/components`) and rewrite the imports accordingly. The CLI rewrites imports for its own UI files, but third-party registry components may use default paths that don't match the project.
|
||||
7. **Switching presets** — Ask the user first: **reinstall**, **merge**, or **skip**?
|
||||
7. **Review added components** — After adding a component or block from any registry, **always read the added files and verify they are correct**. Check for missing sub-components (e.g. `SelectItem` without `SelectGroup`), missing imports, incorrect composition, or violations of the [Critical Rules](#critical-rules). Also replace any icon imports with the project's `iconLibrary` from the project context (e.g. if the registry item uses `lucide-react` but the project uses `hugeicons`, swap the imports and icon names accordingly). Fix all issues before moving on.
|
||||
8. **Registry must be explicit** — When the user asks to add a block or component, **do not guess the registry**. If no registry is specified (e.g. user says "add a login block" without specifying `@shadcn`, `@tailark`, etc.), ask which registry to use. Never default to a registry on behalf of the user.
|
||||
9. **Switching presets** — Ask the user first: **reinstall**, **merge**, or **skip**?
|
||||
- **Reinstall**: `npx shadcn@latest init --preset <code> --force --reinstall`. Overwrites all components.
|
||||
- **Merge**: `npx shadcn@latest init --preset <code> --force --no-reinstall`, then `npx shadcn@latest info` to get installed components, then [smart merge](#updating-components) each one.
|
||||
- **Merge**: `npx shadcn@latest init --preset <code> --force --no-reinstall`, then run `npx shadcn@latest info` to list installed components, then for each installed component use `--dry-run` and `--diff` to [smart merge](#updating-components) it individually.
|
||||
- **Skip**: `npx shadcn@latest init --preset <code> --force --no-reinstall`. Only updates config and CSS, leaves components as-is.
|
||||
|
||||
## Updating Components
|
||||
|
||||
Reference in New Issue
Block a user