Skip to main content

Theme Migration Guide: Vue to React

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.

note

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;
note

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:

  1. A named export for Component, which defines the visual interface of the section.
  2. 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: [],
};
note

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.

info

No changes in global configuration.

Files like settings_data.json and settings_schema.json are the same for both Vue and React themes.


Was this section helpful?