Since Vue and React are fundamentally different frameworks and libraries, it is not possible to automate the migration of one theme into another. However, we will outline the steps developers can use to manually migrate their Vue themes into React themes.
Step 1: Entry file
Both Vue and React themes rely on an entry file to export configured pages. In Vue, this entry file is a js
file whereas in React it is a .jsx
file.
Webpack's dynamic import syntax can be used to create separate chunks for pages.
Step 2: Page level
In Vue, you use the <template>
tag for UI content.
<template>
<!-- Vue UI content -->
</template>
In React, you replace it with a function that returns a React DOM element.
function Home() {
return (
<div className="wrapper">
{/* React UI content */}
</div>
);
}
export default Home;
Step 3: Context props
In Vue themes, specific context props are passed to theme page components from the Vue theme engine for particular data requirements. In React themes, there is no concept of context in the same way. Instead, the useFPI
hook is used to call APIs, and useGlobalStore
retrieves that data from the Redux store.
Vue example
<template>
<div class="categories__cards">
<blog-list
:cardlist="context.blogs"
:cardtype="'CATEGORIES'"
:global_config="global_config"
></blog-list>
</div>
</template>
<script>
<---- Import files ---->
export default {
props: {
context: {},
},
}
React example
import { useGlobalStore, useFPI } from "fdk-core/utils";
import { useEffect } from "react";
function BlogsListPage() {
const fpi = useFPI();
const { loading, items } = useGlobalStore(fpi.getters.BLOGS) || {};
useEffect(() => {
if (!items?.length) {
fpi.content.getBlogs();
}
}, []);
return (
<div>
<blog-list cardlist={items} cardtype="BLOG" />
</div>
);
}
// For API calls on the server-side
BlogsListPage.serverFetch = ({ fpi }) => fpi.content.getBlogs();
Step 4: Action Components
React themes do not rely on Action Components. Instead, an instance of the SDK wrapper (e.g., fpi
) is shared with the theme, and the theme itself manages the API calls and related data.
Instead of using Action Components, React themes are provided with a global hook, useFPI
, which provides an instance of fpi
. This instance can be used to make SDK or GraphQL calls depending on the variant of fdk-store
. In React themes, the theme is allowed to trigger API calls based on the component.
Step 5: Server-side data fetching
In our Vue theme, the <script>
tag has special support for initializeServerProps
, which is used for server-side API calls and stores data in the Vuex component.
Vue example
<script>
// Imports
export default {
// Other Methods and Props
initializeServerProps({ settings, apiSDK }) {
return apiSDK.content
.getBlogs({ pageNo: 1, pageSize: 12 })
.then((data) => data?.items)
.catch((e) => console.log(e));
},
};
</script>
As the React library syntax does not support a <script>
tag, you can write script logic directly in the component itself or in a custom hook.
The same functionality in React can be achieved using serverFetch
, where data is stored in a Redux store. serverFetch
can be used to resolve data required for SSR (Server-Side Rendering) on the server. serverFetch
must be a function that returns a promise.
React example
BlogPage.serverFetch = ({ router, fpi }) => {
const { slug } = router?.params ?? {};
return fpi.content.getBlog({ slug });
};
For a detailed guide on serverFetch
, refer to this documentation.
Step 6: Auth Guard
In React, the authGuard
function is used to control access to specific routes based on the user's authentication status. It ensures that only authenticated users can access certain pages or components.
React example
import React from 'react';
const loginGuard= ({ fpi, store, redirectUrl }) => {
try {
const loggedIn = await isLoggedIn({ fpi, store });
if (loggedIn) {
if (isRunningOnClient()) {
window.location.navigate(redirectUrl ?? "/");
}
return;
}
} catch (error) {
return true;
}
}
function PageWithAuthGuard({ fpi }) {
return (
<>
<PageWithAuthGuard fpi={fpi}>
</PageWithAuthGuard>
</>
);
}
PageWithAuthGuard.authGuard = loginGuard;
export default PageWithAuthGuard;
For more details on authGuard
, refer to this documentation.
Step 7: Settings
Both Vue and React themes support dynamic settings that allow you to configure props and blocks from the platform panel, however, there are syntax differences.
In Vue, the structure is defined using the <settings>
tag, as shown below:
<settings>
{
"props": [
{
"type": "checkbox",
"id": "back_top",
"label": "Back to top",
"default": true
},
]
}
</settings>
In React, you can export the settings
variable in individual theme pages, as shown below:
export const settings = JSON.stringify({
props: [
{
id: "back_top",
label: "Back to top",
type: "checkbox",
default: true,
info: "",
},
],
});
Step 8: Section changes
Similar to Vue themes, React themes also support creating and adding sections. To create a section in React, create a file in the theme > sections
directory. For each section, there must be:
- A named export for
Component
, which defines the visual interface of the section. - A named export for
settings
, which defines the configuration schema for the section.
Server-side data fetching (serverFetch
) in sections is supported in the same way as for other pages.
React example
import React from 'react';
export function Component({ props, blocks }) {
const { code } = props;
return !code?.value ? null : (
<div dangerouslySetInnerHTML={{ __html: code.value }} />
);
}
export const settings = {
label: 'Raw HTML',
props: [
{
id: 'code',
label: 'Your Code Here',
type: 'code',
default: '',
info: 'Add your custom HTML code below. You can also use the full-screen icon to open a code editor and add your code.',
},
],
blocks: [],
};
For more information, refer to the Vue Section and React sections
Step 9: Custom component changes
In Vue, theme developers had to export an object representation of pages to register them as custom templates in the theme. React, on the other hand, supports exporting standard react-router Route
elements, making it simpler for theme developers to create dynamic custom templates.
Vue example
export default {
testpage: {
component: () => import("./example.vue"),
header: false,
footer: false
}
};
React example
import React from "react";
import { Route } from "react-router-dom";
import Cart from "./cart";
import Profile from "./profile";
export default [
<Route path="cart" element={<Cart></Cart>} />,
<Route path="profile" element={<Profile></Profile>} />,
];
Step 10: Webpack upgrade
In React theme, webpack has been upgraded to version 5. Theme developers can extend the webpack configuration as needed. The default webpack configuration is defined in the root path of the theme with the file name webpack.config.js
.
No changes in global configuration.
Files like settings_data.json
and settings_schema.json
are the same for both Vue and React themes.