Migration of Sitecore React Website to Astro
React is a flexible and customizable web framework for building user interfaces. React solely doesn’t have any ability to generate pages on the server side. There could be a few options, on how to add it. One of them is the Astro web framework. Astro pioneered and popularized island architecture. This approach has better front-end performance by helping you avoid monolithic JavaScript patterns. You can split your pages by areas and control the lifecycle of each area with simple attributes.
Astro officially offers the capability of integrating React alongside a set of other frameworks. It simplifies the migration process and makes the barrier to entry sufficiently low for React developers. Our unofficial Sitecore JSS SDK contains an Astro template that allows you to use all Astro benefits on Sitecore headless projects (such as site static generation, island architecture, etc.) Also, it has a sample of usage React components. It means we can migrate the existing React project to Astro with minimal changes in React components.
Let’s go through the migration process, assuming we have an existing Sitecore React JSS project. We want to use Astro for future development, but we don't want to lose earlier-developed functionality on React. Even if there is no final decision React or Astro frameworks will be primary in future development, we still can save and use all the existing React components, start to use Astro, and continue to use both frameworks’ features. If we would like to migrate some React components to Astro, we can make this decision later.
Below is the list of steps we have to do for migration:
-
Create Astro JSS project. We need a new Astro Sitecore JSS project as a base for our migration. First, we will install the clean Astro JSS project and verify that it works with Sitecore. Run the command and set the configurations:
npx @astro-sitecore-jss/create-astro-sitecore-jss@latest
Note: Ensure your settings are equal in Sitecore node and Astro app:
- App name: (react-astro-migration)
- Field: “App Name” of Item: /sitecore/content/Samples/React Astro Migration/Settings
- Field: “Site name” of Item: /sitecore/content/Samples/React Astro Migration/Settings/Site Grouping/React Astro Migration
- Property: “jssAppName” of File ./scjssconfig.json
- Field: “Server side rendering engine endpoint URL” - http://host.docker.internal:4321/api/editing/render
- Field: “ServerSideRenderingEngineApplicationUrl” - http://host.docker.internal:4321/
- Add or Update .gitignore by:
node_modules
,/dist
,/src/temp
Ensure the Astro project properly works in all modes (dev, build, preview), and check Experience Editor can open a new migration site as well
-
Run Astro dev mode
npm run dev
-
Run Astro build mode
npm run build npm run preview
-
Run Sitecore Experience Editor
npm run dev
- App name: (react-astro-migration)
-
Move React components. The first step we should move all React components from the existing React JSS project into a new one. By default, all the components should be placed in the ./src/components folder. If you want to leave Astro components for future work, add all the React components to a separate subfolder (like ./src/components/integrations/react). Otherwise, remove them and add React components directly into the ./src/components folder.
-
Add the component factory. In JSS the component factory is automatically generated by the
bootstrap
npm task. It finds all project components in the source code and compiles them into one file for resolving renderings from the Sitecore Layout service. Every Sitecore JSS template package contains a script for processing only components of the current project type (React JSS - *.jsx only, Vue.js - *.vue, Astro - *.astro, etc.). To include all the React components into a component factory within the Astro project we either should manually update the script for a component factory generation or copy it from the existing JSS React project (it is the simplest way)-
Copy the component factory generator from an existing React project ./scripts/generate-component-factory.js and include it to ./scripts/bootstrap.ts in Astro Project
/* GENERATE CONFIG */ import "./generate-config"; /* GENERATE COMPONENT FACTORY FOR REACT */ import "./generate-component-factory-react"; /* GENERATE COMPONENT FACTORY */ import "./generate-component-factory";
-
Update the component factory path in the file ./scripts/generate-component-factory-react.ts
const componentFactoryPath = path.resolve('src/temp/componentFactory.js');
-
Update the component root path in the file ./scripts/generate-component-factory-react.ts to specify the folder where React components are placed.
const componentRootPath = 'src/components/integrations/react';
-
For every React component change files extension from *.js to *.jsx so all the components can be properly loaded.
-
-
Adopt the application.
-
Create a special component named ReactPlaceholder to put
jss-main
placeholder into the Sitecore context and pass there a react component factory.import React from 'react'; import { Placeholder, SitecoreContext } from '@sitecore-jss/sitecore-jss-react'; import componentFactory from "../../../temp/componentFactory"; const ReactPlaceholder = (props) => { return ( <div> <SitecoreContext layoutData={props.layoutData} componentFactory={componentFactory}> <Placeholder name="jss-main" rendering={props.rendering} componentFactory={componentFactory} /> </SitecoreContext> </div> ); } export default ReactPlaceholder;
-
Update ./layouts/JssLayout.astro to include a new ReactPlaceholder component instead of the standard JSS react placeholder
<body> <Navigation /> <div class="container"> <ReactPlaceholder name="jss-main" rendering={route} layoutData={Astro.props.layoutData}/> </div> </body>
-
Update all the static placeholders in the React components to specify the component library
return ( <div className="row"> <div className="col-sm-8 col-lg-10"> <Placeholder name="jss-styleguide-layout" rendering={props.rendering} componentFactory={componentFactory} /> </div> <div className="col-sm-4 col-lg-2 order-sm-first pt-2">{sections}</div> </div> );
-
Replace the React links across all the components with regular links. They cannot be properly processed. Anyway, we don’t need them as the application we build is not an SPA.
-
To use the dictionary translation feature inside of the React components replace standard i18n translation with
useTranslations
function from the astro package.import { useTranslations } from '@astro-sitecore-jss/astro-sitecore-jss'; const t = useTranslations(); ... <p> This is a static dictionary entry from <code>/data/dictionary</code>: {t('styleguide-sample')} </p>
-
-
Verify an app. When the steps above are done check whether all functionality still works as expected. Run the app in dev mode and check the Experience Editor. Then run build/preview mode and check the prod version.
Summary
After finishing migration we will be able to:
- use all the benefits of the Astro framework
- save exciting functionality of React components and continue to use them
- be able to replace existing React components in the future or leave it as it is
- continue the development with React (if developers prefer it)
- continue the development with Astro
- use static site generation
- use all the features of Experience Editor for Astro and React components
The whole process is pretty straightforward. The initial phase could be done quickly if you don’t have complex customizations inside your React project. You can get the best from two javascript frameworks: the blazing-fast Astro performance based on static site generation and complex client-side application logic using React.