You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 08:28:45