diff --git a/public/logos/create-react-app.svg b/public/logos/create-react-app.svg new file mode 100644 index 0000000000000..7bd1599766bbe --- /dev/null +++ b/public/logos/create-react-app.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/content/docs/en/guides/migrate-to-astro/from-create-react-app.mdx b/src/content/docs/en/guides/migrate-to-astro/from-create-react-app.mdx new file mode 100644 index 0000000000000..ea38bf42ba0c4 --- /dev/null +++ b/src/content/docs/en/guides/migrate-to-astro/from-create-react-app.mdx @@ -0,0 +1,360 @@ +--- +title: Migrating from Create React App (CRA) +description: Tips for migrating an existing Create React App project to Astro +type: migration +stub: true +framework: Create React App +i18nReady: true +--- +import AstroJSXTabs from '~/components/tabs/AstroJSXTabs.astro' +import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro' +import FileTree from '~/components/FileTree.astro' + +Astro's [React integration](/en/guides/integrations-guide/react/) provides support for [using React components inside Astro components](/en/core-concepts/framework-components/), including entire React apps like Create React App (CRA)! + +```astro title="src/pages/index.astro" +--- +// Import your root App component +import App from '../cra-project/App.jsx' +--- + + +``` + +Many apps will "just work" as full React apps when you add them directly to your Astro project with the React integration installed. This is a great way to get your project up and running immediately and keep your app functional while you migrate to Astro. + +Over time, you can convert your structure piece-by-piece to a combination of `.astro` and `.jsx` components. You will probably discover you need fewer React components than you think! + +Here are some key concepts and migration strategies to help you get started. Use the rest of our docs and our [Discord community](https://astro.build/chat) to keep going! + +## Key Similarities between CRA and Astro + +- The [syntax of `.astro` files is similar to JSX](/en/core-concepts/astro-syntax/#differences-between-astro-and-jsx). Writing Astro should feel familiar. + +- Astro uses file-based routing, and [allows specially named pages to create dynamic routes](/en/core-concepts/routing/#dynamic-routes). + +- Astro is [component-based](/en/core-concepts/astro-components/), and your markup structure will be similar before and after your migration. + +- Astro has [official integrations for React, Preact, and Solid](/en/guides/integrations-guide/react/) so you can use your existing JSX components. Note that in Astro, these files **must** have a `.jsx` or `.tsx` extension. + +- Astro has support for [installing NPM packages](/en/guides/imports/#npm-packages), including React libraries. Many of your existing dependencies will work in Astro. + +## Key Differences between CRA and Astro + +When you rebuild your CRA site in Astro, you will notice some important differences: + +- [MPA vs SPA](/en/concepts/mpa-vs-spa/): CRA is a single-page application that uses `index.js` as your project's root. Astro is a multi-page site, and `index.astro` is your home page. + +- [`.astro` components](/en/core-concepts/astro-components/) are not written as exported functions that return page templating. Instead, you'll split your code into a "code fence" for your JavaScript and a body exclusively for the HTML you generate. + +- [Content-first](/en/concepts/why-astro/): Astro was designed to showcase your content and to allow you to opt-in to interactivity only as needed. An existing CRA app might be built for high client-side interactivity and may require advanced Astro techniques to include items that are more challenging to replicate using `.astro` components, such as dashboards. + +## Add your CRA to Astro + +Your existing app can be rendered directly inside a new Astro project, often with no changes to your app's code. + +### Create a new Astro project + +Use the `create astro` command for your package manager to launch Astro's CLI wizard and select a new "empty" Astro project. + + + + ```shell + npm create astro@latest + ``` + + + ```shell + pnpm create astro@latest + ``` + + + ```shell + yarn create astro@latest + ``` + + + +### Add integrations and dependencies +Add the React integration using the `astro add` command for your package manager. If your app uses Tailwind or MDX, you can add multiple Astro integrations using the same command: + +```sh +# Using NPM +npx astro add react +npx astro add react tailwind mdx +# Using Yarn +yarn astro add react +yarn astro add react tailwind mdx +# Using PNPM +pnpm astro add react +yarn astro add react tailwind mdx +``` + +If your CRA requires any dependencies (e.g. NPM packages), then install them individually using the command line or by adding them to your new Astro project's `package.json` manually and then running an install command. Note that many, but not all, React dependencies will work in Astro. + +### Add your existing app files + +Copy your existing Create React App (CRA) project source files and folders (e.g. `components`, `hooks`, `styles`, etc.) into a new folder inside `src/`, keeping its file structure so your app will continue to work. Note that all `.js` file extensions must be renamed to `.jsx` or `.tsx`. + +Do not include any configuration files. You will use Astro's own `astro.config.mjs`, `package.json`, and `tsconfig.json`. + +Move the contents of your app's `public/` folder (e.g. static assets) into Astro's `public/` folder. + + +- public/ + - logo.png + - favicon.ico + - ... +- src/ + - cra-project/ + - App.jsx + - ... + - pages/ + - index.astro +- astro.config.mjs +- package.json +- tsconfig.json + + +### Render your app + +Import your app's root component in the frontmatter section of `index.astro`, then render the `` component in your page template: + +```astro title="src/pages/index.astro" +--- +import App from '../cra-project/App.jsx' +--- + +``` + +:::note[client directives] +Your app needs a [client directive](/en/reference/directives-reference/#client-directives) for interactivity. Astro will render your React app as static HTML until you opt-in to client-side JavaScript. + +Use `client:load` to ensure your app loads immediately from the server, or `client:only="react"` to skip server-side rendering and run your app entirely client-side. +::: + +See our guide for [configuring Astro](/en/guides/configuring-astro/) for more details and available options. + +## Convert your CRA to Astro + +After [adding your existing app to Astro](#add-your-cra-to-astro), you will probably want to convert your app itself to Astro! + +You will replicate a similar component-based design [using Astro HTML templating components for your basic structure](/en/core-concepts/astro-components/) while importing and including individual React components (which may themselves be entire apps!) for islands of interactivity. + +Every migration will look different and can be done incrementally without disrupting your working app. Convert individual pieces at your own pace so that more and more of your app is powered by Astro components over time. + +As you convert your React app, you will decide which React components you will [rewrite as Astro components](#converting-jsx-files-to-astro-files). Your only restriction is that Astro components can import React components, but React components must only import other React components: + +```astro title="src/pages/static-components.astro" ins={2,7} +--- +import MyReactComponent from '../components/MyReactComponent.jsx'; +--- + + +

Use React components directly in Astro!

+ + + +``` + +Instead of importing Astro components into React components, you can nest React components inside a single Astro component: + +```astro title="src/pages/nested-components.astro" {2,3,5,8,10} +--- +import MyReactSidebar from '../components/MyReactSidebar.jsx'; +import MyReactButton from '../components/MyReactButton.jsx'; +--- + +

Here is a sidebar with some text and a button.

+
+ +
+
+``` + + +You may find it helpful to learn about [Astro islands](/en/concepts/islands/) and [Astro components](/en/core-concepts/astro-components/) before restructuring your CRA as an Astro project. + + +### Compare: JSX vs Astro + +Compare the following CRA component and a corresponding Astro component: + + + + ```jsx title="StarCount.jsx" + import React, { useState, useEffect } from 'react'; +import Header from './Header'; +import Footer from './Footer'; + +const Component = () => { + const [stars, setStars] = useState(0); + const [message, setMessage] = useState(''); + + useEffect(() => { + const fetchData = async () => { + const res = await fetch('https://api.github.com/repos/withastro/astro'); + const json = await res.json(); + + setStars(json.stargazers_count || 0); + setMessage(json.message); + }; + + fetchData(); + }, []); + + return ( + <> +
+

Astro has {stars} 🧑‍🚀

+