Can I use this?

This feature is available since v5.13.0.

What you'll learn
  • main features of the React Application scaffold
  • how to continue developing on top of the created application code

Overview
anchor

As the name suggests, the React Application scaffold creates a new standalone React application, on top of which you can build new client-side rendered (CSR) applications. This setup is ideal for secured and non-public-facing applications that do not need to be SEO compatible.

The created application also includes a couple of simple pages and examples which makes it possible to quickly get started with building a new frontend application.

The New React ApplicationThe New React Application
(click to enlarge)

Features
anchor

Clean Setup
anchor

Except for the provided example pages and the base application and cloud infrastructure code, the created React application does not contain any additional code or specific business logic. It’s a clean slate and you can start building on top of the created code in any way you prefer. You can also bring needed libraries, introduce new cloud infrastructure resources, and more.

Be sure to check the Development section below to learn more.

Included Examples
anchor

Out of the box, the newly created React application includes two simple pages - the Home and Not Found (404) pages. These will give you an idea on how to approach solving some of the common requirements like:

  • organization of files and folders
  • defining application routes
  • defining plugins
  • importing styles
  • importing images
  • and more

Once you start building your application, you can remove unnecessary pieces of application code or simply move them into a separate folder, potentially for future reference.

Simple Cloud Infrastructure
anchor

Only a couple of cloud infrastructure resources need to be deployed in order to host a new React application, which is depicted by the following diagram:

Cloud Infrastructure ResourcesCloud Infrastructure Resources
(click to enlarge)

The shown cloud infrastructure resources do not need to be deployed immediately after the scaffolding process has been completed. Frontend application development can still be performed locally, on the developer’s machine.

But, once it’s time to deploy it, you can do that as usual, with the webiny deploy command.

Development
anchor

Usage
anchor

In order to use this scaffold, from your project root, simply run the webiny scaffold command:

yarn webiny scaffold

Then, from the list of all available scaffolds, select React Application and follow the on-screen instructions.

Essential Files and Folders
anchor

The following are the most essential files and folders that are created during the scaffolding process.

New React Application Folder (Some Files Removed for Brevity)
├── code
│   ├── public                    # Contains initial HTML file and meta files.
│   ├── src                       # React application code.
│   │   ├── components            # Shared components go here.
│   │   ├── images                # Images go here.
│   │   ├── plugins               # All plugins go here.
│   │   ├── styles                # All SCSS styles go here.
│   │   ├── App.scss              # SCSS styles entrypoint file.
│   │   ├── App.tsx               # Contains root `App` React component.
│   │   ├── apollo.ts             # Sets up the Apollo GraphQL client.
│   │   └── index.tsx             # Application entrypoint file.
│   ├── package.json              # Package's manifest file.
│   ├── tsconfig.json             # TypeScript config file.
│   └── webiny.config.ts          # Webiny config file (contains build scripts).
├── pulumi                        # Cloud infrastructure code.
│   ├── app.ts
│   ├── cloudfront.ts
│   └── index.ts                  # Cloud infrastructure code entrypoint file.
├── Pulumi.yaml                   # Pulumi project file.
├── tsconfig.json                 # TypeScript configuration used with the Pulumi cloud infrastructure code.
└── webiny.application.ts         # Project application's manifest file.

The path in which the new React application and all of its files and folders are created is specified in the scaffold’s wizard.

code/src/
anchor

Contains the React application code. This is where you’ll be creating your application’s pages, shared React components, defining routes, styles, and more.

code/src/components
anchor

Contains React components that can be shared between multiple pages, for example, a global application layout.

code/src/images
anchor

Contains images that can be imported either from your React component or from SCSS files.

code/src/plugins
anchor

Contains plugins, like RoutePlugin plugins that define application routes or ApolloLinkPlugin plugins that define Apollo links.

code/src/styles
anchor

Contains SCSS files that define styles used by your application. And although, out of the box, this is the only way to define styles, if you maybe prefer a CSS-in-JS solution, you’re always free to add additional libraries.

code/package.json
anchor

In case you missed it, every Webiny project is organized as a monorepo, which can consist of multiple packages. This is the reason why the package.json manifest file exists. It exists because the code folder represents a monorepo workspace .

In most cases, this file will only be modified when new NPM packages are added.

Learn more about the monorepo organization in the Monorepo Organization key topic.

pulumi/
anchor

This is the folder that contains all of the cloud infrastructure code. You’re free to modify in any way needed.

Learn more about Pulumi, the default infrastructure-as-code (IaC) framework Webiny relies on, in the Infrastructure as code with Pulumi key topic.

Deployment
anchor

As mentioned above, frontend application development can still be performed locally, on the developer’s machine.

Which means no initial deployment is needed. Once you’ve completed the scaffold’s wizard and the files have been created, in order to start developing, you can simply start by running the webiny watch command (see below). Only when you actually want to see your application online, you can proceed as usual, by running the webiny deploy command.

In order to deploy your React application, you need to run the following command:

Deploying React Application
yarn webiny deploy {react-application-path} --env {env}

Development Using the Watch Command
anchor

The most straightforward way to continue developing on top of the created code would be via the webiny watch command.

In order to get started, from your project root, simply run the following command:

yarn webiny watch {react-application-path} --env {env}

Except starting a local development server and making your React application locally accessible, this command will also make sure all of the application code changes you perform are immediately reflected in the browser which is running the application.

Creating First Pages
anchor

Once you’ve completed the scaffold’s wizard and the files have been created, the first steps would be to start creating new pages, in the similar fashion it’s already done with the existing example pages. Simply create a new RoutePlugin plugins inside of the code/src/plugins folder, and start creating your page within it, for example:

code/src/plugins/routes/myNewPage.tsx
import React from "react";
import { RoutePlugin } from "@webiny/app/plugins/RoutePlugin";
import { Route, Link, RouteChildrenProps } from "@webiny/react-router";
import { ReactComponent as WebinyLogo } from "../../images/webiny.svg";
import Layout from "../../components/Layout";

function MyNewPage(props: RouteChildrenProps) {
  return (
    <Layout className={"my-new-page"}>
      <h1>My New Page</h1>
      <h2>This is my new page.</h2>
      <Link to={"/"}> &larr; Back</Link>
    </Layout>
  );
}

// We register routes via the `RoutePlugin` plugin.
export default new RoutePlugin({
  route: <Route path="/my-new-page" exact component={MyNewPage} />,
});

Furthermore, every application has one or more layouts, so you can also start editing the code/src/components/Layout.tsx . Feel free to remove anything that’s not needed. The styles for the layout can be found in the code/src/styles/global.scss file.

Linking the React Application With a GraphQL API
anchor

Out of the box, the new React application scaffold also includes the Apollo GraphQL (v2) client, which you can use to perform queries and mutations against an existing GraphQL API.

But, unless the new React application was created with the New Full-Stack Application scaffold, you will have to manually link your React application with an existing GraphQL API.

For example, let’s say our application needs to interact with the main GraphQL API that’s, by default, set up with every Webiny project and is deployed as part of the API project application, located within the api folder.

In order to do this, upon starting a new watch session or building our application, we need to set the REACT_APP_GRAPHQL_API_URL environment variable and assign the URL over which the GraphQL API is actually accessible.

So, we need to add the following lines into the code/webiny.config.ts :

ts webiny.config.ts
import invariant from "invariant";import { createWatchApp, createBuildApp } from "@webiny/project-utils";import { getStackOutput } from "@webiny/cli-plugin-deploy-pulumi/utils";
const MAP = { REACT_APP_GRAPHQL_API_URL: "${apiUrl}/graphql",};
const NO_ENV_MESSAGE = `Please specify the environment via the "--env" argument, for example: "--env dev".`;
// Exports fundamental watch and build commands.// Need to inject environment variables or link your application with an existing GraphQL API?// See https://www.webiny.com/docs/how-to-guides/scaffolding/react-application/webiny-config.export default {commands: {  async watch(options, context) {   invariant(options.env, NO_ENV_MESSAGE);   Object.assign(process.env, getStackOutput("api", options.env, MAP));
    // Starts local application development.    const watch = createWatchApp({ cwd: __dirname });    await watch(options);  },  async build(options, context) {    invariant(options.env, NO_ENV_MESSAGE);    Object.assign(process.env, getStackOutput("api", options.env, MAP));
    // Creates a production build of your application, ready to be deployed to    // a hosting provider of your choice, for example Amazon S3.    const build = createBuildApp({ cwd: __dirname });    await build(options);  }}};

As shown, within both commands, we rely on the deployed GraphQL API (api) and its stack output to retrieve the URL over which the GraphQL API is accessible. If needed, additional values can be retrieved too, but keep in mind that they need to be exported in the cloud infrastructure code, in api/pulumi/dev/index.ts and api/pulumi/prod/index.ts files.

The same steps would have to be followed if we wanted to link our React application with the Headless CMS GraphQL API or maybe with a new standalone GraphQL API, created with the GraphQL API scaffold. The only thing that would change is the folder that’s being passed to the getStackOutput function.

FAQ
anchor

Is server-side rendering (SSR) supported?
anchor

No.

The React Application scaffold creates a new standalone React application, on top of which you can build client-side rendered (CSR) applications. This is ideal for secured and non-public-facing applications that do not need to be SEO compatible.

If you need server-side rendering (SSR), then you might want to look into other frameworks, such as Next.js .

For development purposes, into which environment should I deploy?
anchor

You can use any name as the name of the environment, but common practice is to use dev, for example:

yarn webiny watch {react-application-path} --env dev

Can I modify commands specified within the webiny.config.ts file?
anchor

You certainly can. You can also add new commands, if need be.

How can I add new libraries to the created React application?
anchor

In case you missed it, every Webiny project is organized as a monorepo, which can consist of multiple packages. This is the reason why the code/package.json manifest file exists. It exists because the code folder represents a monorepo workspace .

This is also the reason why we can’t just run yarn add xyz from our project root. We need to specify to which yarn workspace the new library needs to be added, which can be done via the yarn workspace {workspace-name} add {library-name} command.

So, let’s say we wanted to add the react-helmet library to our newly created React application that’s created within the new-react-app folder. To add the library, we’d use the following command:

yarn workspace new-react-app add react-helmet

Note that the name of the workspace is defined in the workspace’s package.json file, via the name property (traditionally used to define the package name). In case of the new-react-app React application, that would be in new-react-app/code/package.json file.

Do I need to deploy the created React application in order to continue development?
anchor

No. As mentioned above, frontend application development can still be performed locally, on the developer’s machine. You only deploy the application when you need to have it online.