@carlonicora/nextjs-jsonapi

中文文档
6.31.0发布于 2026/11/09GPL-3.0-or-laterTypeScriptESM + CJS构建来源已验证近 30 天下载 1.3万

Next.js JSON:API 客户端有服务器/客户端支持并缓存

中文使用文档
文档目录43 节
  1. 目录
  2. 特征
  3. 建筑
  4. 4: 0的改变
  5. 安装
  6. Git 子模块设置( 替代)
  7. 同伴依赖关系
  8. 快速启动
  9. 1. 配置API客户端
  10. 2. 定义您的模块和起步器
  11. 3. 在服务器组件中获取数据
  12. 4. 在客户端组件中使用钩子
  13. 环境变量
  14. 条目点
  15. 主导出( E) . (中文(简体) )
  16. 核心项目 /core (中文(简体) )
  17. 客户 /client (中文(简体) )
  18. 服务器( U) /server (中文(简体) )
  19. 缓冲 /cached-get (中文(简体) )
  20. 权限( 在 /core (中文(简体) )
  21. 特性模块(在 /core (中文(简体) )
  22. 公用事业 /core (中文(简体) )
  23. 构成部分( /components (中文(简体) )
  24. 其他条目
  25. 统一 API
  26. JsonApiGet (英语)
  27. JsonApi 邮局
  28. JsonApiPut / JsonApiPatch 密码
  29. JsonApiDelete (英语)
  30. 客户钩
  31. 使用 JsonApiGet 软件
  32. 使用 JsonApi 组合
  33. 服务器请求
  34. 快取配置文件
  35. 权限
  36. 阴影/
  37. 标准UI组件(41)
  38. 自定义组件(3)
  39. 用法示例
  40. 尾风 CSS 配置
  41. CSS 变量
  42. 许可证
  43. 作者

@carlonicora/nextjs-jsonapi (英语)

一个全面的Next.js软件包为JSON:API兼容客户端提供统一的服务器/客户端支持,自动缓存,以及完整的shadcn/ui组件库.

目录

特征

  • 统一 API: 自动检测环境(服务器/客户端)并使用适当的请求方法
  • JSON:API 合规: 完整的 JSON: API 规格支持与去线化和平面化
  • 下一个.js 16+ 缓存: 内建支持 cacheLife() 财务报告和审定财务报表 cacheTag() 通过缓存配置文件
  • 反应钩数字 : useJsonApiGet 财务报告和审定财务报表 useJsonApiMutation 用于获取客户端数据
  • 服务器组件: 直接服务器侧取取数据并自动处理符号
  • 多用途支助: B2B 应用程序的内建公司ID处理
  • 文件上传: 无连接文件上传支持, 有多部分请求
  • 阴影/: 44个预建的UI组件(41个标准+3个自定义)
  • 工具函数数字 : cn 类合并、移动检测和参考组成

建筑

图书馆按这些入境点排列 exports 地图在 package.json:

@carlonicora/nextjs-jsonapi
├── (main)               # Unified API, configuration functions, and everything in /core
├── /core                # Interfaces, factories, registries, permissions, feature modules, and utilities
├── /server              # Server-side requests, ServerSession, and cache tag helpers
├── /cached-get          # cachedServerGet: the token-free "use cache" GET (server only)
├── /client              # React hooks and client-side utilities
├── /components          # Library components and the 44 shadcn/ui components
├── /contexts            # React providers (SessionProvider, ViewportProvider, SocketProvider, ...)
├── /contexts/styles.css # Stylesheet for the contexts entry
├── /testing             # Test utilities (mock providers, render helpers)
├── /billing             # Stripe billing components (kept apart so Stripe.js is not loaded globally)
├── /help                # Help feature, client components
├── /help/server         # Help feature, server-safe constants and types
├── /tokenusage          # Token-usage admin feature, client components
├── /analytics           # Analytics feature, client components
├── /analytics/server    # Analytics feature, server page components
└── /next-config         # createNextConfig for next.config.js

4: 0的改变

4.0使图书馆在下16.4缓存组件下工作. 完整的食谱,随着破碎的改变和工作顺序,在 文件/迁移至4.0.md简言之:

  • 缓存组件数字 : createNextConfig 打开 cacheComponents 财务报告和审定财务报表 partialPrefetching。应用程序框架在它后面的会话流出时在静态外壳中制作.
  • 会议数字 : ServerSession.read() (单位:千美元)/server返回 a Promise<SessionSnapshot> 由饼干和信头建造。 不用等就叫它来 答应我 SessionProvider (单位:千美元)/contexts(三); useSession() 解开它,所以它的召唤者坐在它的后面 <Suspense>。 。 。 .
  • 供应商接受 session数字 : ViewportProvider, (中文(简体) ), SocketProvider (单位:千美元)/contexts和 SidebarProvider (单位:千美元)/components接受 session?: Promise<SessionSnapshot>. 旧道具(token, (中文(简体) ), initialIsMobile, (中文(简体) ), defaultOpen还行.
  • createNextConfig 从 /next-config数字 : cspRemove 不见了 CSP的第三方来自 services (单位:千美元)"stripe" | "googleMaps" | "turnstile" | "discord" | "googleFonts"); 任何其它内容 csp。 。 。 .
  • 缓存: 一个模块的 cache 值是一个 cacheLife 配置文件名称或标签。 缓存服务器通过 cachedServerGet (单位:千美元)/cached-get页:1 "use cache" 函数,从不发送符号。 见 快取配置文件。 。 。 .
  • configureI18n 需求 getLocale:通过下一轮 getLocale 从 next-intl/server; 图书馆不再导入下层 .

安装

pnpm add @carlonicora/nextjs-jsonapi

Git 子模块设置( 替代)

如果您想要将软件包用作git子模块(用于开发或npm发布前):

1. 添加子模块

cd /path/to/your-project
git submodule add https://github.com/carlonicora/nextjs-jsonapi packages/nextjs-jsonapi

2. 核实有效

git submodule status
# Should show: <commit-sha> packages/nextjs-jsonapi (heads/master)

3. 提交子模块

git add .gitmodules packages/nextjs-jsonapi
git commit -m "Add nextjs-jsonapi as submodule"

4. 更新您的 package.json (例如, apps/web/package.json(中文(简体) )

{
  "dependencies": {
    "@carlonicora/nextjs-jsonapi": "workspace:*"
  }
}

5. 确保 pnpm-workspace.yaml 包括软件包

packages:
  - "apps/*"
  - "packages/*"

6. 安装和建造

pnpm install
cd packages/nextjs-jsonapi && pnpm build && cd ../..

CI/CD(GitHub 动作),添加 submodules: recursive 到您的退出步骤 :

- uses: actions/checkout@v4
  with:
    submodules: recursive

用子模块克隆一个项目:

# When cloning fresh
git clone --recurse-submodules https://github.com/your/repo.git

# If already cloned
git submodule update --init --recursive

同伴依赖关系

软件包版本需求目的
next>=16.4.0对下一个框架
react>=19.3.0对反应库
react-dom>=19.3.0对反应 DOM
react-hook-form页:1可选表格处理(形式组件)

快速启动

1. 配置API客户端

在您的环境设置文件中配置 JSON: API 客户端 :

// src/config/env.ts
import { configureJsonApi } from "@carlonicora/nextjs-jsonapi";
import { bootstrap } from "@/config/Bootstrapper";

configureJsonApi({
  apiUrl: process.env.NEXT_PUBLIC_API_URL!,
  bootstrapper: bootstrap,
});

2. 定义您的模块和起步器

为模块注册(用于 Modules.X 和 DataClass Registry (用于 JSON: API 响应翻译):

// src/config/Bootstrapper.ts
import { DataClassRegistry, FieldSelector, ModuleRegistry } from "@carlonicora/nextjs-jsonapi/core";
import { ModuleWithPermissions } from "@carlonicora/nextjs-jsonapi/core";
import { S3Module } from "@carlonicora/nextjs-jsonapi/core";

// Import your module definitions
import { ArticleModule } from "@/features/article/ArticleModule";
import { UserModule } from "@/features/user/UserModule";
import { Article } from "@/features/article/data/Article";
import { User } from "@/features/user/data/User";

// Module factory helper
const moduleFactory = (params: {
  pageUrl?: string;
  name: string;
  cache?: string;
  model: any;
  feature?: string;
  moduleId?: string;
  inclusions?: Record<string, { types?: string[]; fields?: FieldSelector<any>[] }>;
}): ModuleWithPermissions => ({
  pageUrl: params.pageUrl,
  name: params.name,
  model: params.model,
  feature: params.feature,
  moduleId: params.moduleId,
  cache: params.cache,
  inclusions: params.inclusions ?? {},
});

// Example module definition file (e.g., ArticleModule.ts)
// export const ArticleModule = (factory: ModuleFactory) =>
//   factory({ name: "articles", model: Article, pageUrl: "/articles" });

// Single source of truth for all modules
const allModules = {
  Article: ArticleModule(moduleFactory),
  User: UserModule(moduleFactory),
  S3: S3Module(moduleFactory), // Built-in S3 module from library
} satisfies Record<string, ModuleWithPermissions>;

// Export type for TypeScript autocompletion
export type AllModuleDefinitions = typeof allModules;

let bootstrapped = false;

export function bootstrap(): void {
  if (bootstrapped) return;

  // Register modules for Modules.X access
  Object.entries(allModules).forEach(([name, module]) => {
    ModuleRegistry.register(name, module);
  });

  // Register model classes for JSON:API response translation
  DataClassRegistry.bootstrap(allModules);

  bootstrapped = true;
}

3. 在服务器组件中获取数据

// src/app/articles/page.tsx
import { JsonApiGet } from "@carlonicora/nextjs-jsonapi";
import { Modules } from "@carlonicora/nextjs-jsonapi/core";

export default async function ArticlesPage() {
  const response = await JsonApiGet({
    classKey: Modules.Article,
    endpoint: "/articles",
    language: "en",
  });

  if (!response.ok) {
    return <div>Error: {response.error}</div>;
  }

  return (
    <ul>
      {response.data.map((article) => (
        <li key={article.id}>{article.title}</li>
      ))}
    </ul>
  );
}

4. 在客户端组件中使用钩子

"use client";

import { useJsonApiGet, useJsonApiMutation } from "@carlonicora/nextjs-jsonapi/client";
import { Modules } from "@carlonicora/nextjs-jsonapi/core";

export function ArticleList() {
  const { data, loading, error, refetch } = useJsonApiGet({
    classKey: Modules.Article,
    endpoint: "/articles",
  });

  const { mutate, loading: creating } = useJsonApiMutation({
    method: "POST",
    classKey: Modules.Article,
    onSuccess: () => refetch(),
  });

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      <button
        onClick={() => mutate({
          endpoint: "/articles",
          body: { title: "New Article" }
        })}
        disabled={creating}
      >
        Create Article
      </button>
      <ul>
        {data.map((article) => (
          <li key={article.id}>{article.title}</li>
        ))}
      </ul>
    </div>
  );
}

环境变量

# Required
NEXT_PUBLIC_API_URL=http://localhost:3000

# Optional - Token cookie name (default: "token")
# Set this if your API uses a different cookie name for JWT tokens

条目点

主导出( E).(中文(简体) )

默认导出提供了自动检测环境的统一 API :

import {
  JsonApiGet,
  JsonApiPost,
  JsonApiPut,
  JsonApiPatch,
  JsonApiDelete,
  configureJsonApi,
} from "@carlonicora/nextjs-jsonapi";

核心项目/core(中文(简体) )

核心接口、工厂、登记册和公用事业:

import {
  // Interfaces
  ApiDataInterface,
  ApiRequestDataTypeInterface,
  ApiResponseInterface,

  // Factories
  JsonApiDataFactory,

  // Registries
  ModuleRegistry, // Register modules during bootstrap
  DataClassRegistry, // Register model classes for JSON:API translation
  Modules, // Access registered modules (e.g., Modules.Article)

  // Endpoint builder
  EndpointBuilder,

  // Field selectors
  FieldSelector,

  // Utilities
  translateResponse,
} from "@carlonicora/nextjs-jsonapi/core";

客户/client(中文(简体) )

反应钩和客户端公用事业(要求) "use client":

import {
  // Hooks
  useJsonApiGet,
  useJsonApiMutation,
  useRehydration,

  // Context
  JsonApiProvider,
  useJsonApiContext,

  // Request utilities
  directFetch,
  getClientToken,
} from "@carlonicora/nextjs-jsonapi/client";

服务器( U)/server(中文(简体) )

服务器端请求工具 :

import {
  serverRequest,
  getServerToken,
  ServerSession, // read(), isLogged(), checkPermission(), ...
  invalidateCacheTag,
  invalidateCacheTags,
  updateCacheTag,
  CACHE_PROFILES,
} from "@carlonicora/nextjs-jsonapi/server";

缓冲/cached-get(中文(简体) )

免签 "use cache" 获取。 它决定了真正的功能 react-server 仅限条件;其他捆绑都有一个会扔出活塞的活塞. serverRequest 召人来见你们 快取配置文件) (中文(简体) ).

import { cachedServerGet, statusFromDigest } from "@carlonicora/nextjs-jsonapi/cached-get";

权限( 在 /core(中文(简体) )

权限检查工具输出自 /core (并主入道:

import {
  checkPermissions,
  Action,
  type PermissionCheck,
  type ModuleWithPermissions,
  type ModuleFactory,
} from "@carlonicora/nextjs-jsonapi/core";

特性模块(在 /core(中文(简体) )

可直接用于应用程序的内建功能模块:

import {
  // S3 Module (for file uploads via pre-signed URLs)
  S3Module, // Module definition factory
  S3Service, // Service with getPreSignedUrl, getSignedUrl, deleteFile
  S3, // Data class
  type S3Interface, // Response interface
  type S3Input, // Input parameters
} from "@carlonicora/nextjs-jsonapi/core";

// Usage example:
const s3Response = await S3Service.getPreSignedUrl({
  key: "companies/123/documents/file.pdf",
  contentType: "application/pdf",
  isPublic: true,
});

await fetch(s3Response.url, {
  method: "PUT",
  headers: s3Response.headers,
  body: file,
});

公用事业 /core(中文(简体) )

工具函数 :

import {
  cn, // Class name merger (clsx + tailwind-merge)
  composeRefs, // Compose multiple refs
  useComposedRefs, // Hook for composing refs
  useIsMobile, // Mobile detection hook
  type ClassValue, // Type for cn function
} from "@carlonicora/nextjs-jsonapi/core";

构成部分(/components(中文(简体) )

库本身的组件加上所有shadcn/ui组件(需要) "use client":

import {
  // UI Components (41)
  Accordion,
  AccordionItem,
  AccordionTrigger,
  AccordionContent,
  Alert,
  AlertTitle,
  AlertDescription,
  AlertDialog,
  AlertDialogTrigger,
  AlertDialogContent /* ... */,
  Avatar,
  AvatarImage,
  AvatarFallback,
  Badge,
  badgeVariants,
  Breadcrumb,
  BreadcrumbList,
  BreadcrumbItem /* ... */,
  Button,
  buttonVariants,
  Calendar,
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter,
  Carousel,
  CarouselContent,
  CarouselItem,
  CarouselPrevious,
  CarouselNext,
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  ChartLegend /* ... */,
  Checkbox,
  Collapsible,
  CollapsibleTrigger,
  CollapsibleContent,
  Command,
  CommandInput,
  CommandList,
  CommandItem /* ... */,
  ContextMenu,
  ContextMenuTrigger,
  ContextMenuContent /* ... */,
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogHeader /* ... */,
  Drawer,
  DrawerTrigger,
  DrawerContent /* ... */,
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent /* ... */,
  Form,
  FormField,
  FormItem,
  FormLabel,
  FormControl /* ... */,
  HoverCard,
  HoverCardTrigger,
  HoverCardContent,
  Input,
  Label,
  NavigationMenu,
  NavigationMenuList,
  NavigationMenuItem /* ... */,
  Popover,
  PopoverTrigger,
  PopoverContent,
  Progress,
  RadioGroup,
  RadioGroupItem,
  ScrollArea,
  ScrollBar,
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem /* ... */,
  Separator,
  Sheet,
  SheetTrigger,
  SheetContent,
  SheetHeader /* ... */,
  Sidebar,
  SidebarProvider,
  SidebarContent,
  SidebarMenu /* ... */,
  Skeleton,
  Slider,
  Sonner,
  Toaster,
  toast,
  Switch,
  Table,
  TableHeader,
  TableBody,
  TableRow,
  TableHead,
  TableCell /* ... */,
  Tabs,
  TabsList,
  TabsTrigger,
  TabsContent,
  Textarea,
  Toggle,
  toggleVariants,
  Tooltip,
  TooltipTrigger,
  TooltipContent,
  TooltipProvider,

  // Custom Components (3)
  Kanban,
  KanbanColumn,
  KanbanItem, // Drag-and-drop Kanban board
  Link, // next-intl compatible Link
  MultiSelect, // Multi-select dropdown
} from "@carlonicora/nextjs-jsonapi/components";

其他条目

入境点它所持有的
/contexts反应提供者 : SessionProvider编号 :useSession, (中文(简体) ), ViewportProvider, (中文(简体) ), SocketProvider和更多
/contexts/styles.css随上下文条目一起运出样式表
/testingMockJsonApiProvider, (中文(简体) ), renderWithProviders, (中文(简体) ), createMockApiData, (中文(简体) ), createMockResponse,, , , , , , , , .
/billing条纹计费组件和上下文
/help帮助功能客户端组件( U)HelpProvider, (中文(简体) ), HelpHeader, (...) (中文(简体) )
/help/server服务器安全 HELP_MODES 和帮助文章类型
/tokenusageToken-usage 附加功能客户端组件
/analytics分析功能客户端组件( A)AnalyticsTracker, (...) (中文(简体) )
/analytics/serverAnalyticsAdminPage, (中文(简体) ), AnalyticsJourneyPage 服务器组件
/next-configcreateNextConfig 页:1 next.config.js (见 文件/迁移至4.0.md(中文(简体) )
/messages/*en.json, (中文(简体) ), it.json: 图书馆提供的文本(见 文献/图书馆(中文(简体) )

图书馆自带英文和意大利文;一个应用程序根据自己的信息将其与 mergeMessages 说明 文献/图书馆。 。 。 .

统一 API

统一的API自动检测代码是否运行在服务器或客户端上,并使用适当的请求方法.

JsonApiGet (英语)

从 JSON: API 端点获取数据 :

const response = await JsonApiGet({
  classKey: Modules.Article, // Module definition
  endpoint: "/articles/123", // API endpoint
  companyId: "company-uuid", // Optional: for multi-tenant apps
  language: "en", // Required: for i18n
});

if (response.ok) {
  console.info(response.data); // Deserialized data
  console.info(response.pagination); // Pagination info

  // Navigate pages
  if (response.next) {
    const nextPage = await response.nextPage();
  }
}

JsonApi 邮局

创建新资源 :

const response = await JsonApiPost({
  classKey: Modules.Article,
  endpoint: "/articles",
  body: { title: "New Article", content: "..." },
  language: "en",

  // Optional
  files: { attachment: file }, // File uploads
  overridesJsonApiCreation: false, // Use raw body instead of JSON:API format
  responseType: Modules.OtherType, // If response type differs
});

JsonApiPut / JsonApiPatch 密码

更新资源 :

const response = await JsonApiPut({
  classKey: Modules.Article,
  endpoint: "/articles/123",
  body: { title: "Updated Title" },
  language: "en",
});

JsonApiDelete (英语)

删除资源 :

const response = await JsonApiDelete({
  classKey: Modules.Article,
  endpoint: "/articles/123",
  language: "en",
});

客户钩

使用 JsonApiGet 软件

自动调试获取数据的钩 :

const {
  data, // Fetched data or null
  loading, // Loading state
  error, // Error message or null
  response, // Full API response
  refetch, // Manual refetch function
  hasNextPage, // Pagination: has next page
  hasPreviousPage, // Pagination: has previous page
  fetchNextPage, // Fetch next page
  fetchPreviousPage, // Fetch previous page
} = useJsonApiGet<Article>({
  classKey: Modules.Article,
  endpoint: `/articles/${id}`,
  companyId: companyId,
  options: {
    enabled: !!id, // Conditionally enable
    deps: [someDependency], // Refetch when these change
  },
});

使用 JsonApi 组合

钩子变异(POST, PUT, PATCH, DELETE):

const {
  data, // Result data or null
  loading, // Loading state
  error, // Error message or null
  response, // Full API response
  mutate, // Execute the mutation
  reset, // Reset state
} = useJsonApiMutation<Article>({
  method: "POST",
  classKey: Modules.Article,
  onSuccess: (data) => console.info("Created:", data),
  onError: (error) => console.error("Failed:", error),
});

// Execute mutation
const result = await mutate({
  endpoint: "/articles",
  body: { title: "New Article" },
  files: { image: imageFile },
  companyId: "company-uuid",
});

服务器请求

对于服务器组件或API路由,直接使用服务器模块:

import { serverRequest, getServerToken } from "@carlonicora/nextjs-jsonapi/server";

// Per-user data: no `cache`, so this is a plain uncached fetch that sends the token
export async function getMyArticle(id: string) {
  return serverRequest({
    method: "GET",
    url: `${process.env.NEXT_PUBLIC_API_URL}/articles/${id}`,
    token: await getServerToken(),
    language: "en",
  });
}

// Shared data: a GET with `cache` goes through cachedServerGet and never sends the token
export async function getPublicArticle(id: string) {
  return serverRequest({
    method: "GET",
    url: `${process.env.NEXT_PUBLIC_API_URL}/articles/${id}`,
    cache: "articles", // a cacheLife profile name, or a tag
    language: "en",
  });
}

快取配置文件

一个模块 cache 值决定服务器端 GET 如何被缓存 。 每一个得到一个 cache 值在内部运行 cachedServerGet页:1 "use cache" 函数 :

  • a 内置 cacheLife 配置文件名称( e)"seconds", (中文(简体) ), "minutes", (中文(简体) ), "hours", (中文(简体) ), "days", (中文(简体) ), "weeks", (中文(简体) ), "max", (中文(简体) ), "default"页:1 cacheLife(profile)· ;
  • 任何其它值都是标记 ~ cacheTag(value) + 键 cacheLife("max"),所以该条目将一直存在,直到您取消标记.
// In your module definition
const ArticleModule = (factory: ModuleFactory) =>
  factory({ name: "articles", model: Article, cache: "articles" }); // tag

// JsonApiGet on the server applies it automatically, and does not read the token
// cookie for a cached module

// After a write, expire the tag
await updateCacheTag("articles"); // Server Actions: the same request reads fresh data
await invalidateCacheTag("articles"); // elsewhere: stale-while-revalidate

缓存路径是无符号的: 参数是缓存密钥, 因此请求会不包含 Authorization。需要一个符号的终点是每个用户,其模块不能设置 cache。失败的响应被扔出而不是存储;其状态在 error.digest 作为 HTTP_<status> 财务报告和审定财务报表 statusFromDigest 读回.

权限

检查保护资源的用户权限 :

import { Action, checkPermissions, Modules } from "@carlonicora/nextjs-jsonapi/core";

// Check if user has permission
const canEdit = checkPermissions({
  module: Modules.Article,
  action: Action.Update,
  user: currentUser,
  data: article,
});

if (!canEdit) {
  return <div>Access denied</div>;
}

阴影/

该包包括44个预建的shadcn/ui组件:

标准UI组件(41)

构成部分说明
Accordion可折叠的内容部分
Alert对重要消息的点名
AlertDialog确认的模块对话框
Avatar用户配置图像
Badge状况指标和标签
Breadcrumb导航面包屑
Button单击带有变体的动作
Calendar摘取日期日历
Card内容容器
Carousel滑动内容面板
Chart数据可视化(Recharts)
Checkbox切换选项
Collapsible可扩展区域
Command命令调色板( cmdk)
ContextMenu右键菜单
Dialog模块窗口
Drawer滑动侧面板(Vaul)
DropdownMenu下放菜单
Form表格处理(反应- hook-form)
HoverCard交接卡
Input文本输入字段
Label表格标签
NavigationMenu导航菜单
Popover浮动内容
Progress进度指标
RadioGroup无线电按钮组
ScrollArea自定义滚动条
Select下拉选择
Separator视觉分隔符
Sheet侧面小组讨论
Sidebar应用程序边栏
Skeleton正在装入占位符
Slider区域滑动器
Sonner托拉斯通知
Switch切换开关
Table数据表
Tabs标签界面
Textarea多行文本输入
Toggle切换按钮
Tooltip隐藏工具提示

自定义组件(3)

构成部分说明
Kanban拖放 Kanban 棋盘( dnd- kit)
Link下个兼容链接包
MultiSelect多选择带徽章的下拉

用法示例

"use client";

import {
  Button,
  Card,
  CardHeader,
  CardTitle,
  CardContent,
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@carlonicora/nextjs-jsonapi/components";
import { cn } from "@carlonicora/nextjs-jsonapi/core";

export function ArticleCard({ article, className }) {
  return (
    <Card className={cn("hover:shadow-lg transition-shadow", className)}>
      <CardHeader>
        <CardTitle>{article.title}</CardTitle>
      </CardHeader>
      <CardContent>
        <p>{article.excerpt}</p>

        <Dialog>
          <DialogTrigger>
            <Button variant="outline">Read More</Button>
          </DialogTrigger>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>{article.title}</DialogTitle>
            </DialogHeader>
            <p>{article.content}</p>
          </DialogContent>
        </Dialog>
      </CardContent>
    </Card>
  );
}

尾风 CSS 配置

对 Tailwind v4 很重要: 您必须添加 @source 给您的指令 globals.css 以确保 Tailwind 扫描软件包组件文件 :

/* apps/web/src/app/globals.css */
@import "tailwindcss";
@import "tw-animate-css";

/* Include package source files for Tailwind to scan */
@source "../../../../packages/nextjs-jsonapi/src/**/*.{ts,tsx}";

@custom-variant dark (&:is(.dark *));

@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  /* ... other theme variables */
}

这个 @source 路径应该是相对的 globals.css 切换到软件包 src 目录.

CSS 变量

Shadcn/ui 组件需要您在应用程序中定义 CSS 变量 。 把这些添加到您的 globals.css数字 :

:root {
  /* Background & Foreground */
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);

  /* Primary */
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);

  /* Secondary */
  --secondary: oklch(0.97 0 0);
  --secondary-foreground: oklch(0.205 0 0);

  /* Muted */
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);

  /* Accent */
  --accent: oklch(0.97 0 0);
  --accent-foreground: oklch(0.205 0 0);

  /* Destructive */
  --destructive: oklch(0.577 0.245 27.325);
  --destructive-foreground: oklch(0.985 0 0);

  /* Border & Input */
  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);

  /* Card & Popover */
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.145 0 0);
  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0.145 0 0);

  /* Charts */
  --chart-1: oklch(0.646 0.222 41.116);
  --chart-2: oklch(0.6 0.118 184.704);
  --chart-3: oklch(0.398 0.07 227.392);
  --chart-4: oklch(0.828 0.189 84.429);
  --chart-5: oklch(0.769 0.188 70.08);

  /* Sidebar */
  --sidebar: oklch(0.985 0 0);
  --sidebar-foreground: oklch(0.145 0 0);
  --sidebar-primary: oklch(0.205 0 0);
  --sidebar-primary-foreground: oklch(0.985 0 0);
  --sidebar-accent: oklch(0.97 0 0);
  --sidebar-accent-foreground: oklch(0.205 0 0);
  --sidebar-border: oklch(0.922 0 0);
  --sidebar-ring: oklch(0.708 0 0);

  /* Warning */
  --warning: oklch(0.84 0.16 84);
  --warning-foreground: oklch(0.28 0.07 46);

  /* Radius */
  --radius: 0.625rem;
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --card: oklch(0.205 0 0);
  --card-foreground: oklch(0.985 0 0);
  --popover: oklch(0.269 0 0);
  --popover-foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --secondary: oklch(0.269 0 0);
  --secondary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.269 0 0);
  --muted-foreground: oklch(0.708 0 0);
  --accent: oklch(0.269 0 0);
  --accent-foreground: oklch(0.985 0 0);
  --destructive: oklch(0.704 0.191 22.216);
  --destructive-foreground: oklch(0.985 0 0);
  --border: oklch(1 0 0 / 10%);
  --input: oklch(1 0 0 / 15%);
  --ring: oklch(0.556 0 0);
  /* ... other dark mode values */
}

许可证

此项目在GPL v3下获得开源使用许可.

商业/封闭源码许可证,联系: @卡尔隆科拉

作者

卡罗・尼科拉 @卡尔隆科拉

版本与发布记录

@carlonicora/nextjs-jsonapi 共发布 425 个版本,首次发布于 2025/12/10;过去 12 个月发布了 425 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
6.31.0latest2026/11/09今天
6.30.02026/11/09今天
6.29.12026/11/09今天
6.29.02026/11/08今天
6.28.02026/11/081 天前
6.27.02026/11/081 天前

关于 @carlonicora/nextjs-jsonapi 的常见问题

@carlonicora/nextjs-jsonapi 是什么?

Next.js JSON:API 客户端有服务器/客户端支持并缓存

如何安装 @carlonicora/nextjs-jsonapi?

在项目目录运行 npm install @carlonicora/nextjs-jsonapi,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:next(>=16.4.0)、react(>=19.3.0)、react-dom(>=19.3.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 generate-web-module,可以用 npx generate-web-module 直接运行。

@carlonicora/nextjs-jsonapi 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@carlonicora/nextjs-jsonapi 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@carlonicora/nextjs-jsonapi 可以商用吗?

@carlonicora/nextjs-jsonapi 使用 GPL-3.0-or-later 许可。强 Copyleft:分发包含该代码的软件时,整个作品需以 GPL-3.0 兼容许可开源,并附带专利与反锁定条款。仅内部使用不触发此义务。以上为概括,不构成法律意见,请以许可原文为准。

@carlonicora/nextjs-jsonapi 的下载量有多少?

根据 npm 官方下载统计,@carlonicora/nextjs-jsonapi 在 2026/10/09 – 2026/11/07 这 30 天内被下载 12,509 次,日均约 417 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@carlonicora/nextjs-jsonapi 还在维护吗?

最新版本 6.31.0 发布于 2026/11/09(今天);至今共发布 425 个版本,其中过去 12 个月发布了 425 个;首次发布于 2025/12/10。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。