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

如何在NextJS中集成Stencil Web Components并实现SSR(非CSR)

在Next.js中实现Stencil Web Components的服务端渲染(SSR)

首先保留你之前在next.config.js中配置的transpilePackages,确保Next.js能正确转译Stencil组件包:

/** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ['your-stencil-package-name'],
  // 其他原有配置
};

module.exports = nextConfig;

接下来按以下步骤配置SSR:

1. 确认Stencil组件库支持SSR输出

检查你的stencil.config.ts,确保输出目标包含dist-hydrate-script(SSR核心依赖)和dist-custom-elements,如果没有则修改配置后重新发布NPM包:

export const config: Config = {
  outputTargets: [
    {
      type: 'dist-custom-elements',
      customElementsExportBehavior: 'auto-define-custom-elements',
    },
    {
      type: 'dist-hydrate-script',
    },
    // 其他原有输出目标
  ],
};

2. 在Next.js中引入Hydration脚本

修改_document.tsx(或_document.jsx),引入Stencil生成的hydrate脚本,用于客户端接管服务端渲染的组件:

import Document, { Html, Head, Main, NextScript } from 'next/document';

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx);
    return { ...initialProps };
  }

  render() {
    return (
      <Html>
        <Head>
          {/* 从node_modules复制hydrate.js到public目录,或直接引用包内路径 */}
          <script src="/hydrate.js" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

3. 封装服务端兼容的Stencil组件

创建一个通用封装组件StencilComponent.tsx,统一处理服务端渲染和客户端hydration:

import React, { useEffect, useRef } from 'react';

type StencilComponentProps = {
  tagName: string;
  [key: string]: any;
};

export default function StencilComponent({ tagName, ...props }: StencilComponentProps) {
  const componentRef = useRef<HTMLElement>(null);

  useEffect(() => {
    // 客户端确保组件注册完成
    if (typeof window !== 'undefined') {
      import('your-stencil-package-name');
    }
  }, []);

  return React.createElement(tagName, { ref: componentRef, ...props });
}

使用示例:

import StencilComponent from '../components/StencilComponent';

export default function Home() {
  return (
    <div>
      <StencilComponent tagName="your-custom-component" prop1="demo-value" />
    </div>
  );
}

4. 服务端执行组件Hydrate

修改_app.tsx(或_app.jsx),在服务端初始化Stencil的hydrate逻辑,确保服务端能生成组件的静态HTML:

import type { AppProps } from 'next/app';
import { hydrate } from 'your-stencil-package-name/hydrate';

function MyApp({ Component, pageProps }: AppProps) {
  // 仅在服务端执行hydrate
  if (typeof window === 'undefined') {
    hydrate();
  }

  return <Component {...pageProps} />;
}

export default MyApp;

5. 验证SSR效果

启动Next.js开发服务器后,右键查看页面源代码,如果能看到自定义组件的完整DOM结构(而非仅自定义标签),说明SSR生效;同时测试组件交互,确保客户端hydration正常完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 10:02:42