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 />
关键说明
- 路由组件规范:react-router v6中,必须用
Routes组件包裹所有Route规则,这是定义客户端路由的标准方式,直接返回createBrowserRouter生成的对象会导致React无法渲染。 - Shopify路由同步:你的App组件中已经正确配置了传给
AppBridgeProvider的router对象,该对象会同步react-router的路由状态到Shopify后台导航,确保内嵌应用的路由行为符合Shopify的要求。 - 组件命名避坑:将自定义路由组件命名为
AppRoutes,避免和react-router-dom提供的Routes组件重名,减少代码混淆。
内容的提问来源于stack exchange,提问作者Pavel Shepelenko
相关产品推荐
相关产品推荐

