NextJS 13升级Sanity应用时PortableText TypeScript错误求助
解决NextJS 13升级后PortableText类型错误及urlFor问题
一、修复的类型不兼容错误
1. 同步依赖包版本
首先确保@portabletext/react、sanity及相关类型包版本兼容,NextJS 13建议搭配Sanity v3+及对应版本的@portabletext/react:
npm install @portabletext/react@latest sanity@latest @sanity/types@latest
2. 明确类型定义,修正组件使用
- 导入正确的类型,给
value和components指定明确类型,避免类型推断偏差:
import { PortableText } from "@portabletext/react"; import type { PortableTextBlock } from "@sanity/types"; import type { PortableTextComponents } from "@portabletext/react"; // 定义从Sanity获取的内容类型 const portableTextContent: PortableTextBlock[] = [...]; // 明确components的类型 const components: PortableTextComponents = { types: { // 自定义组件配置 image: ({ value }) => { /* ... */ }, }, // 可添加heading、list等其他块级组件自定义配置 };
- 确保
value属性传入的是PortableTextBlock[]类型,而非其他数组类型。
二、修复img标签的urlFor属性错误
1. 正确初始化urlFor工具函数
从@sanity/image-url导入并传入Sanity客户端实例,同时指定正确的参数类型:
import imageUrlBuilder from '@sanity/image-url'; import { client } from './path-to-your-sanity-client'; // 你的Sanity客户端实例 import type { ImageAsset } from "@sanity/types"; const builder = imageUrlBuilder(client); export function urlFor(source: ImageAsset | undefined) { if (!source) throw new Error('No image source provided'); return builder.image(source); }
2. 在PortableText图片组件中正确使用urlFor
如果使用原生<img>标签:
// 加入到components.types配置中 image: ({ value }) => { if (!value?.asset) return null; return ( <img src={urlFor(value.asset).width(800).quality(85).url()} alt={value.alt || 'Untitled image'} loading="lazy" /> ); },
如果使用NextJS 13的<Image>组件(推荐):
import Image from 'next/image'; // 加入到components.types配置中 image: ({ value }) => { if (!value?.asset) return null; const imageUrl = urlFor(value.asset).width(800).quality(85).url(); return ( <Image src={imageUrl} alt={value.alt || 'Untitled image'} width={800} height={600} // 可根据图片比例调整,或使用fill模式 loading="lazy" /> ); },
- 注意:使用NextJS
<Image>时,需要在next.config.js中配置Sanity图片域名:
/** @type {import('next').NextConfig} */ const nextConfig = { images: { domains: ['cdn.sanity.io'], }, }; module.exports = nextConfig;
额外注意事项
- 若使用NextJS 13的App Router(app目录),需给使用
PortableText的组件添加'use client'指令,因为@portabletext/react依赖客户端运行环境:
'use client'; import { PortableText } from "@portabletext/react"; // 其他导入和组件代码
内容的提问来源于stack exchange,提问作者Don
相关产品推荐
相关产品推荐

