Skip to content

06 Setup React

JP Barbosa edited this page Sep 24, 2022 · 11 revisions

Setup React Frontend

Diagram

Frontend

Create frontend stack

code ./stacks/resources/site.ts
import {
  Api,
  Bucket,
  Stack,
  ViteStaticSite,
} from "@serverless-stack/resources";

type CreateSiteOptions = {
  api: Api;
  bucket: Bucket;
};

type CreateSite = (stack: Stack, options: CreateSiteOptions) => ViteStaticSite;

export const createSite: CreateSite = (stack, { api, bucket }) =>
  new ViteStaticSite(stack, "site", {
    path: "frontend",
    environment: {
      VITE_API_URL: api.url,
      VITE_API_REGION: stack.region,
      VITE_API_BUCKET_NAME: bucket.bucketName,
    },
  });

Update resources index

code ./stacks/resources/index.ts
...
export * from "./site";

Update stack

code ./stacks/MyStack.ts
...
import {
  ...
  createSite,
} from "./resources";

export function MyStack({ stack }: StackContext) {
  ...
  const site = createSite(stack, { api, bucket });

  stack.addOutputs({
    ApiEndpoint: api.url,
    SiteUrl: site.url,
  });
}

Create React app with Vite

npm create vite@latest frontend -- --template react-ts
(cd ./frontend && npm install)

Install additional packages

(cd ./frontend && npm install axios moment vite-plugin-svgr)
(cd ./frontend && npm install --save-dev @serverless-stack/static-site-env)

Configure run dev to use SST

code ./frontend/package.json
  ...
  "scripts": {
    "dev": "sst-env -- vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  ...

Configure vite-plugin-svgr

code ./frontend/vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import svgr from "vite-plugin-svgr";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react(), svgr()],
  define: {
    global: {},
  },
});

Clean frontend directory

rm ./frontend/public/vite.svg
rm ./frontend/src/App.css
rm ./frontend/src/assets/react.svg

Update index

code ./frontend/index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <link rel="icon" type="image/svg+xml" href="/rekognition.svg" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>SST Rekognition</title>
  <meta name="description" content="An event-driven app to label images on top of AWS">
</head>

<body>
  <div id="root"></div>
  <script type="module" src="/src/main.tsx"></script>
</body>

</html>

Create header component

code ./frontend/src/components/Header.tsx
/// <reference types="vite-plugin-svgr/client" />

import { ReactComponent as Rekognition } from "../assets/rekognition.svg";

export const Header: React.FC = () => {
  return (
    <header>
      <div className="title">
        <Rekognition />
        <div>
          <h1>SST Rekognition</h1>
          <p className="subtitle">
            An event-driven app to label images on top of AWS
          </p>
        </div>
      </div>
      <div>
        <a
          href="https://github.com/jpbarbosa/sst-rekognition"
          target="_blank"
          className="button"
        >
          GitHub
        </a>
      </div>
    </header>
  );
};

Create status component

code ./frontend/src/components/Status.tsx
import React from "react";

type StatusItem = {
  condition: boolean;
  message: string;
};

type StatusProps = {
  status: StatusItem[];
};

export const Status: React.FC<StatusProps> = ({ status }) => {
  const renderStatus = () => {
    for (const item of status) {
      if (item.condition) {
        return (
          <div className="status">
            <div className="message">{item.message}</div>
          </div>
        );
      }
    }
  };

  return <>{renderStatus()}</>;
};

Create/Change app component

code ./frontend/src/App.tsx
import React from "react";
import { Header } from "./components/Header";

function App() {
  return (
    <div id="app">
      <Header />
      <div className="content"></div>
    </div>
  );
}

export default App;

Download required assets

(cd ./frontend/src && curl -OL https://raw.githubusercontent.com/jpbarbosa/sst-rekognition/main/frontend/src/index.css)
(cd ./frontend/public && curl -OL https://raw.githubusercontent.com/jpbarbosa/sst-rekognition/main/frontend/public/rekognition.svg)
(cd ./frontend/src/assets && curl -OL https://raw.githubusercontent.com/jpbarbosa/sst-rekognition/main/frontend/src/assets/rekognition.svg)
(cd ./frontend/src/assets && curl -OL https://raw.githubusercontent.com/jpbarbosa/sst-rekognition/main/frontend/src/assets/arrow.svg)

Deploy changes

npm start # or press ENTER to redeploy if SST is already running

Start React

(cd ./frontend && npm run dev)
image

Commit

git add .
git commit -m "Setup React Frontend"

Next step

Context