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

Magnolia CMS NextJS混合SSG开发:组件如何获取内容类型数据?

在Magnolia CMS + Next.js混合SSG项目中实现内容类型列表组件的方案

方案1:组件内直接调用Magnolia Delivery API

这种方式适合需要动态加载内容的场景,编辑在AdminCentral里配置组件时,只需指定要展示的内容类型标识,组件在渲染时自行请求数据。

  • 第一步:在Magnolia中给组件添加对话框字段,让编辑选择/输入目标内容类型的名称(比如contentType字段)。
  • 第二步:在Next.js组件中,通过useEffect或数据请求库调用Magnolia Delivery API获取对应内容:
import { useEffect, useState } from 'react';

export default function ContentListComponent(props) {
  const [contentItems, setContentItems] = useState([]);
  const { contentType } = props; // 编辑器配置的内容类型字段

  useEffect(() => {
    if (!contentType) return;

    // 替换为你的Magnolia实例Delivery API地址
    fetch(`https://your-magnolia-instance.com/.rest/delivery/v1/${contentType}`)
      .then(res => res.json())
      .then(data => setContentItems(data.results))
      .catch(err => console.error('获取内容失败:', err));
  }, [contentType]);

  return (
    <div className="content-list">
      {contentItems.map(item => (
        <div key={item['@id']} className="content-item">
          <h3>{item.title}</h3>
          <p>{item.description}</p>
        </div>
      ))}
    </div>
  );
}
  • 注意事项:
    • 配置Next.js代理避免CORS问题,或确保Delivery API对外可访问。
    • 用SWR/React Query做缓存和重新验证,提升性能。
    • 确保AdminCentral预览环境下API请求能正常到达Magnolia实例。

方案2:扩展页面getStaticProps预取内容(SSG友好)

如果希望内容在静态生成阶段就完成预渲染,可在pages/[[pathname]].js的getStaticProps中提前解析页面组件配置,预取对应内容类型的数据后传递给组件。

  • 第一步:同样在组件对话框中添加contentType配置字段。
  • 第二步:在页面的getStaticProps中遍历组件树,批量预取内容:
export async function getStaticProps(context) {
  // 原有获取页面内容的逻辑
  const pageContent = await fetchMagnoliaPageContent(context.params.pathname);
  
  const contentRequests = [];
  const targetComponents = [];

  // 递归遍历组件,收集需要预取内容的组件
  function traverseComponents(components) {
    components.forEach((component, index) => {
      if (component['@nodeType'] === 'your-content-list-component-type' && component.contentType) {
        targetComponents.push({ index, contentType: component.contentType });
        contentRequests.push(
          fetch(`https://your-magnolia-instance.com/.rest/delivery/v1/${component.contentType}`)
            .then(res => res.json())
        );
      }
      // 处理嵌套组件
      if (component.components) traverseComponents(component.components);
    });
  }

  if (pageContent.components) traverseComponents(pageContent.components);

  // 批量请求内容数据
  const contentResults = await Promise.all(contentRequests);

  // 将数据注入对应组件的props
  targetComponents.forEach(({ index }, resultIndex) => {
    pageContent.components[index].contentData = contentResults[resultIndex].results;
  });

  return {
    props: { pageContent },
    revalidate: 60, // 可选:开启增量静态再生,定期更新内容
  };
}
  • 第三步:组件直接使用预取的contentData:
export default function ContentListComponent(props) {
  const { contentData } = props;

  return (
    <div className="content-list">
      {contentData.map(item => (
        <div key={item['@id']} className="content-item">
          <h3>{item.title}</h3>
          <p>{item.description}</p>
        </div>
      ))}
    </div>
  );
}
  • 注意事项:
    • 需准确匹配组件的@nodeType,避免误处理其他组件。
    • 递归遍历要覆盖组件嵌套的场景(如容器组件内的子组件)。

方案3:利用Magnolia Next.js集成工具的内置方法

Magnolia官方的@magnolia/nextjs-connector包提供了简化的内容获取方式,可直接在组件中调用内置方法获取内容类型数据。

  • 第一步:确保已安装并配置@magnolia/nextjs-connector。
  • 第二步:在组件中使用上下文获取客户端并请求内容:
import { useMagnoliaContext } from '@magnolia/nextjs-connector';
import { useEffect, useState } from 'react';

export default function ContentListComponent(props) {
  const { contentType } = props;
  const { client } = useMagnoliaContext();
  const [contentItems, setContentItems] = useState([]);

  useEffect(() => {
    if (!client || !contentType) return;

    async function fetchContent() {
      try {
        const response = await client.getNodes(contentType);
        setContentItems(response.results);
      } catch (err) {
        console.error('获取内容失败:', err);
      }
    }

    fetchContent();
  }, [client, contentType]);

  return (
    <div className="content-list">
      {contentItems.map(item => (
        <div key={item['@id']} className="content-item">
          <h3>{item.title}</h3>
          <p>{item.description}</p>
        </div>
      ))}
    </div>
  );
}
  • 注意事项:
    • 需在_app.js中正确配置MagnoliaContext,确保客户端实例正常初始化。
    • 该方式会自动处理API路径和认证配置,减少手动编码工作量。

内容的提问来源于stack exchange,提问作者Subin Paul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:06:08