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

Next.js客户端路由下Xola嵌入组件加载异常及无限刷新问题

解决Next.js客户端路由下Xola嵌入组件不加载的问题

问题分析

当前代码里的window.location.reload()会触发客户端渲染→页面刷新→SSR重新渲染→再触发客户端刷新的无限循环。而Xola组件不加载的核心原因是:Xola的嵌入脚本仅在页面首次加载时扫描DOM并初始化组件,但Next.js客户端路由是单页跳转,不会重新执行脚本,所以新渲染的Xola容器元素无法被初始化。

解决方案

1. 移除无限刷新逻辑

首先删掉{isSsr ? null : window.location.reload()},终止循环。

2. 手动触发Xola组件初始化

通过useEffect监听路由完成事件,在组件挂载/路由切换后,手动加载Xola脚本并调用官方初始化方法,确保新渲染的DOM元素被识别。

修改后的代码示例

checkout.js
import Head from "next/head";
import { useRouter } from "next/router";
import { Container, Button } from "@mui/material";
import { makeStyles } from "@mui/styles";
import { CheckoutCard } from "../components/layout/directory";
import { useEffect, useRef } from "react";

function Checkout() {
  const router = useRouter();
  const classes = useStyles();
  const xolaScriptLoaded = useRef(false); // 标记脚本是否已加载

  useEffect(() => {
    const initXolaCheckout = () => {
      // 优先调用Xola官方初始化方法
      if (window.Xola) {
        window.Xola.initEmbeds();
      } else {
        // 未加载脚本则动态插入
        const script = document.createElement('script');
        script.src = 'https://xola.com/js/embed.js';
        script.async = true;
        script.onload = () => {
          xolaScriptLoaded.current = true;
          window.Xola?.initEmbeds();
        };
        document.body.appendChild(script);
      }
    };

    // 路由切换完成后触发初始化
    const handleRouteChange = () => initXolaCheckout();
    router.events.on('routeChangeComplete', handleRouteChange);
    // 组件挂载时初始化一次
    initXolaCheckout();

    // 清理事件监听
    return () => router.events.off('routeChangeComplete', handleRouteChange);
  }, [router]);

  return (
    <>
      <Head>
        <title>checkout</title>
      </Head>
      <Container className={classes.root}>
        <Button
          className={classes.btn}
          onClick={router.back}
          color="secondary"
          variant="contained"
        >
          back
        </Button>
        <CheckoutCard />
      </Container>
    </>
  );
}

const useStyles = makeStyles((theme) => ({
  root: { marginTop: theme.spacing(10) },
  btn: { marginBottom: theme.spacing(5) },
}));

export default Checkout;
CheckoutCard.js(保持原结构无需修改)
function CheckoutCard() {
  return (
    <div
      className="xola-embedded-checkout"
      data-seller="5f3d889683cfdc77b119e592"
      data-experience="5f3d8d80d6ba9c6b14748160"
      data-version="2"
      id="xola-checkout"
    ></div>
  );
}

export default CheckoutCard;

关键说明

  • 动态加载脚本:用useRef标记脚本加载状态,避免全局重复插入脚本。
  • 路由事件监听:监听routeChangeComplete确保客户端路由跳转后,新DOM能被Xola初始化。
  • 官方API调用:window.Xola.initEmbeds()是Xola嵌入脚本的标准方法,用于重新扫描DOM并初始化所有嵌入组件,比强制刷新页面更高效可靠。

备选方案(若Xola无公开初始化方法)

如果Xola未提供官方初始化API,可以通过更新组件key强制重新挂载容器,触发脚本的自动扫描:

import { useState, useEffect } from "react";
import { useRouter } from "next/router";

function CheckoutCard() {
  const router = useRouter();
  const [componentKey, setComponentKey] = useState(Date.now());

  useEffect(() => {
    const handleRouteChange = () => setComponentKey(Date.now());
    router.events.on('routeChangeComplete', handleRouteChange);
    return () => router.events.off('routeChangeComplete', handleRouteChange);
  }, [router]);

  return (
    <div
      key={componentKey}
      className="xola-embedded-checkout"
      data-seller="5f3d889683cfdc77b119e592"
      data-experience="5f3d8d80d6ba9c6b14748160"
      data-version="2"
      id="xola-checkout"
    ></div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:18:18