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

Shopify内嵌应用中React Router客户端路由配置求助

Shopify内嵌应用中React Router路由配置问题解决

问题描述

我正在Shopify内嵌应用中尝试用react-router实现客户端路由,参考了Shopify官方指南,但不清楚./Routes文件该怎么写,搜索到的相关信息都比较陈旧。以下是我的现有代码:

原App.jsx代码

import {
  ApolloClient,
  ApolloProvider,
  HttpLink,
  InMemoryCache,
} from "@apollo/client";
import {
  Provider as AppBridgeProvider,
  useAppBridge,
} from "@shopify/app-bridge-react";
import { authenticatedFetch } from "@shopify/app-bridge-utils";
import { Redirect } from "@shopify/app-bridge/actions";
import { AppProvider as PolarisProvider } from "@shopify/polaris";
import translations from "@shopify/polaris/locales/en.json";
import "@shopify/polaris/build/esm/styles.css";

import {useMemo} from 'react';
import {useLocation, useNavigate, BrowserRouter} from 'react-router-dom';

import { HomePage } from "./components/HomePage";
import Routes from './Routes';

function App() {
  const navigate = useNavigate();
  const location = useLocation();
  const history = useMemo(
    () => ({replace: (path) => navigate(path, {replace: true})}),
    [navigate],
  );
  console.log(new URLSearchParams(document.location.search).get("host"))  
  const router = useMemo(
    () => ({
      location,
      history,
    }),
    [location, history],
  );
  return (
    <PolarisProvider i18n={translations}>
      <AppBridgeProvider
        config={{
          apiKey: process.env.SHOPIFY_API_KEY,
          host: new URLSearchParams(document.location.search).get("host"),
          forceRedirect: true,
        }}
        router={router}
      >
        <MyProvider>
            <Routes />
        </MyProvider>
      </AppBridgeProvider>
    </PolarisProvider>
  );
}

function MyProvider({ children }) {
  const app = useAppBridge();

  const client = new ApolloClient({
    cache: new InMemoryCache(),
    link: new HttpLink({
      credentials: "include",
      fetch: userLoggedInFetch(app),
    }),
  });

  return <ApolloProvider client={client}>{children}</ApolloProvider>;
}

export function userLoggedInFetch(app) {
  const fetchFunction = authenticatedFetch(app);

  return async (uri, options) => {
    const response = await fetchFunction(uri, options);

    if (
      response.headers.get("X-Shopify-API-Request-Failure-Reauthorize") === "1"
    ) {
      const authUrlHeader = response.headers.get(
        "X-Shopify-API-Request-Failure-Reauthorize-Url"
      );

      const redirect = Redirect.create(app);
      redirect.dispatch(Redirect.Action.APP, authUrlHeader || `/auth`);
      return null;
    }

    return response;
  };
}

export default function AppWrapper() {
  return (
    <BrowserRouter>
      <App />
    </BrowserRouter>
  );
}

原Routes.jsx代码

import React from 'react';
import {createBrowserRouter} from "react-router-dom";
import { HomePage } from './components/HomePage';
import { Instructions } from './components/Instructions';

export default function Routes() { 
    const routes = createBrowserRouter([
        {
        path: "/",
        element: <HomePage />,
        },
        {
            path: "/statistics",
            element: <HomePage />,
        },
        {
            path: "/integration",
            element: <Instructions />,
        }
    ]);

    return  routes
}

解决方案

你的核心问题在于错误使用createBrowserRouter并直接返回路由对象,这不符合React组件的返回要求,同时和已有的BrowserRouter产生冲突。结合Shopify App Bridge的路由同步需求,推荐使用react-router v6标准的Routes+Route组件写法,具体修正如下:

修正后的Routes.jsx

import React from 'react';
import { Routes, Route } from "react-router-dom";
import { HomePage } from './components/HomePage';
import { Instructions } from './components/Instructions';

// 重命名组件避免和react-router的Routes组件重名
export default function AppRoutes() { 
    return (
        <Routes>
            <Route path="/" element={<HomePage />} />
            <Route path="/statistics" element={<HomePage />} />
            <Route path="/integration" element={<Instructions />} />
        </Routes>
    );
}

同步修改App.jsx的引入

将原App.jsx中的路由组件引入改为:

import AppRoutes from './Routes';

并在JSX中替换为:

<AppRoutes />

关键说明

  1. 路由组件规范:react-router v6中,必须用Routes组件包裹所有Route规则,这是定义客户端路由的标准方式,直接返回createBrowserRouter生成的对象会导致React无法渲染。
  2. Shopify路由同步:你的App组件中已经正确配置了传给AppBridgeProvider的router对象,该对象会同步react-router的路由状态到Shopify后台导航,确保内嵌应用的路由行为符合Shopify的要求。
  3. 组件命名避坑:将自定义路由组件命名为AppRoutes,避免和react-router-dom提供的Routes组件重名,减少代码混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:45:27