From b7f2ac56f071f3d1c364252153af8dbfb6e83bfe Mon Sep 17 00:00:00 2001 From: josefaidt Date: Fri, 20 Sep 2024 10:26:24 -0700 Subject: [PATCH 1/4] update js quickstart --- .../[platform]/start/quickstart/index.mdx | 191 +++++++----------- 1 file changed, 73 insertions(+), 118 deletions(-) diff --git a/src/pages/[platform]/start/quickstart/index.mdx b/src/pages/[platform]/start/quickstart/index.mdx index ae339cb1935..834b0ab6f5a 100644 --- a/src/pages/[platform]/start/quickstart/index.mdx +++ b/src/pages/[platform]/start/quickstart/index.mdx @@ -21,11 +21,11 @@ export const meta = { }; -export const getStaticPaths = async () => { +export function getStaticPaths() { return getCustomStaticPath(meta.platforms); -}; +} -export function getStaticProps(context) { +export function getStaticProps() { const childPageNodes = getChildPageNodes(meta.route); return { props: { @@ -39,56 +39,56 @@ export function getStaticProps(context) { 👋 Welcome to AWS Amplify! In this quickstart guide, you will: -1. Deploy a Vanilla JavaScript app with Vite +1. Deploy a Vanilla JavaScript app with [Vite](https://vitejs.dev/) 2. Build and connect to a database with real-time data updates 3. Configure authentication and authorization rules - ## Create project -Create a new Vanilla JavaScript app with vite using the following commands, create the directory (`amplify-js-app`) and files for the app. +Create a new Vanilla JavaScript app with Vite using the following commands, create the directory (`amplify-js-app`) and files for the app. -```bash +```bash title="Terminal" showLineNumbers={false} npm create vite@latest ✔ Project name: amplify-js-app ✔ Select a framework: › Vanilla ✔ Select a variant: › TypeScript ``` -Initialize npm and install dependencies and dev dependencies. -```bash +Use npm to install dependencies and start Vite's local development server. + +```bash title="Terminal" showLineNumbers={false} cd amplify-js-app npm install npm run dev ``` -This runs a development server and allows you to see the output generated by the build. You can see the running app by navigating to [http://localhost:5173](http://localhost:5173). +The development server allows you to see the output generated by the build. You can see the running app by navigating to [`http://localhost:5173`](http://localhost:5173). Add the following to the `index.html` file: ```html title="index.html" - - - + + + Todo App - - + +
-

My todos

- - -
- Try creating a new todo. -
- - Review next step of this tutorial. - -
+

My todos

+ + +
+ Try creating a new todo. +
+ + Review next step of this tutorial. + +
- + ``` @@ -165,11 +165,11 @@ a { ``` {/* cSpell:enable */} -In `main.js` remove the boilerplate code and leave it empty. Then refresh the browser to see the changes. +In `main.ts` remove the boilerplate code and leave it empty. Then refresh the browser to see the changes. ## Create Backend -The easiest way to get started with AWS Amplify is through npm with `create-amplify` command. You can run it from your base project directory. +The easiest way to get started with AWS Amplify is through npm with [`create-amplify`](https://www.npmjs.com/package/create-amplify) package. It is recommended to be run from the root of your project's directory. ```bash title="Terminal" showLineNumbers={false} npm create amplify@latest @@ -185,6 +185,7 @@ Running this command will scaffold Amplify backend files in your current project │ ├── data/ │ │ └── resource.ts │ ├── backend.ts +│ ├── tsconfig.json │ └── package.json ├── node_modules/ ├── index.html @@ -197,9 +198,9 @@ Running this command will scaffold Amplify backend files in your current project ### Set up local AWS credentials -To make backend updates, we are going to require AWS credentials to deploy backend updates from our local machine. +To make backend updates, you will need AWS credentials to deploy backend updates from your local machine. -**Skip ahead to step 8**, if you already have an AWS profile with credentials on your local machine, and your AWS profile has the `AmplifyBackendDeployFullAccess` permission policy. +**Skip ahead** if you already have an AWS profile with credentials on your local machine, and your AWS profile has the `AmplifyBackendDeployFullAccess` permission policy. Otherwise, **[set up local AWS credentials](/[platform]/start/account-setup/)** that grant Amplify permissions to deploy backend updates from your local machine. @@ -215,67 +216,66 @@ Once the sandbox environment is deployed, it will create a GraphQL API, database ## Connect frontend to backend -The initial scaffolding already has a pre-configured data backend defined in the `amplify/data/resource.ts` file. The default example will create a Todo model with `content` field. Update your main.js file to create new to-do items. +The initial scaffolding already has a pre-configured data backend defined in the `amplify/data/resource.ts` file. The default example will create a Todo model with `content` field. Update your `main.ts` file to create new to-do items. -```typescript title="src/main.ts" -import { generateClient } from "aws-amplify/data"; -import type { Schema } from "../amplify/data/resource"; -import './style.css'; +```ts title="src/main.ts" +import type { Schema } from '../amplify/data/resource'; +import { generateClient } from 'aws-amplify/data'; import { Amplify } from 'aws-amplify'; import outputs from '../amplify_outputs.json'; +import './style.css'; Amplify.configure(outputs); - const client = generateClient(); -document.addEventListener("DOMContentLoaded", function () { - const todos: Array = []; - const todoList = document.getElementById("todoList") as HTMLUListElement; - const addTodoButton = document.getElementById("addTodo") as HTMLButtonElement; +document.addEventListener('DOMContentLoaded', function () { + const todos: Array = []; + const todoList = document.getElementById('todoList') as HTMLUListElement; + const addTodoButton = document.getElementById('addTodo') as HTMLButtonElement; + + addTodoButton.addEventListener('click', createTodo); - addTodoButton.addEventListener("click", createTodo); + function updateUI() { + todoList.innerHTML = ''; + todos.forEach((todo) => { + const li = document.createElement('li'); + li.textContent = todo.content ?? ''; + todoList.appendChild(li); + }); + } - function updateUI() { - todoList.innerHTML = ''; - todos.forEach(todo => { - const li = document.createElement('li'); - li.textContent = todo.content ?? ''; - todoList.appendChild(li); + function createTodo() { + console.log('createTodo'); + const content = window.prompt('Todo content'); + if (content) { + client.models.Todo.create({ content }) + .then((response) => { + if (response.data && !response.errors) { + todos.push(response.data); + updateUI(); + } else { + console.error('Error creating todo:', response.errors); + alert('Failed to create todo.'); + } + }) + .catch((error) => { + console.error('Network or other error:', error); + alert('Failed to create todo due to a network or other error.'); }); } - - function createTodo() { - console.log('createTodo'); - const content = window.prompt("Todo content"); - if (content) { - client.models.Todo.create({ content }).then(response => { - if (response.data && !response.errors) { - todos.push(response.data); - updateUI(); - } else { - console.error('Error creating todo:', response.errors); - alert('Failed to create todo.'); - } - }).catch(error => { - console.error('Network or other error:', error); - alert('Failed to create todo due to a network or other error.'); - }); - } } - - client.models.Todo.observeQuery().subscribe({ - next: (data) => { - todos.splice(0, todos.length, ...data.items); - updateUI(); - } - }); + client.models.Todo.observeQuery().subscribe({ + next: (data) => { + todos.splice(0, todos.length, ...data.items); + updateUI(); + } + }); }); ``` - 👋 Welcome to AWS Amplify! In this quickstart guide, you will: @@ -578,11 +578,6 @@ git push Once your build completes in the Amplify Console, the `main` backend will update to support the changes made within the cloud sandbox. The data in the cloud sandbox is fully isolated and won't pollute your production database. - - - - - 👋 Welcome to AWS Amplify! In this quickstart guide, you will: @@ -596,9 +591,6 @@ We have two Quickstart guides you can follow: - - - 👋 Welcome to AWS Amplify! In this quickstart guide, you will: @@ -912,13 +904,6 @@ git push Once your build completes in the Amplify Console, the `main` backend will update to support the changes made within the cloud sandbox. The data in the cloud sandbox is fully isolated and won't pollute your production database. - - - - - - - 👋 Welcome to AWS Amplify! In this quickstart guide, you will: @@ -1238,12 +1223,6 @@ Once your build completes in the Amplify Console, the `main` backend will update - - - - - - ## Prerequisites @@ -1678,16 +1657,6 @@ You can terminate the sandbox environment now to clean up the project. Publishing changes to the cloud requires a remote git repository. Amplify offers fullstack branch deployments that allow you to automatically deploy infrastructure and application code changes from feature branches. To learn more, visit the [fullstack branch deployments guide](/[platform]/deploy-and-host/fullstack-branching/branch-deployments). - - - - - - - - - - ## Prerequisites @@ -2137,10 +2106,6 @@ You can terminate the sandbox environment now to clean up the project. Publishing changes to the cloud requires a remote git repository. Amplify offers fullstack branch deployments that allow you to automatically deploy infrastructure and application code changes from feature branches. To learn more, visit the [fullstack branch deployments guide](/[platform]/deploy-and-host/fullstack-branching/branch-deployments). - - - - 👋 Welcome to AWS Amplify! In this quickstart guide, you will: @@ -2601,15 +2566,6 @@ npx @aws-amplify/backend-cli generate outputs --out-dir app/src/main/res/raw --a - - - - - - - - - ## Prerequisites @@ -2934,7 +2890,6 @@ You can terminate the sandbox environment now to clean up the project. Publishing changes to the cloud requires a remote git repository. Amplify offers fullstack branch deployments that allow you to automatically deploy infrastructure and application code changes from feature branches. To learn more, visit the [fullstack branch deployments guide](/[platform]/deploy-and-host/fullstack-branching/branch-deployments). - ## 🥳 Success From 27225246345ef90dae065542b791308c1026d851 Mon Sep 17 00:00:00 2001 From: josefaidt Date: Fri, 20 Sep 2024 16:46:53 -0700 Subject: [PATCH 2/4] start vite-react rewrite --- .../authenticator-localhost-(720p).png | Bin 0 -> 44238 bytes .../[platform]/start/quickstart/index.mdx | 253 ++++++++++++++++-- 2 files changed, 233 insertions(+), 20 deletions(-) create mode 100644 public/images/gen2/getting-started/authenticator-localhost-(720p).png diff --git a/public/images/gen2/getting-started/authenticator-localhost-(720p).png b/public/images/gen2/getting-started/authenticator-localhost-(720p).png new file mode 100644 index 0000000000000000000000000000000000000000..ee07e8a581c5d4f81e60493d5fc68e846a6007ba GIT binary patch literal 44238 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 - -Create repository from template - +Next, scaffold your Amplify backend using the [`create-amplify`](https://www.npmjs.com/package/create-amplify) package: -Use the form in GitHub to finalize your repo's creation. +```bash title="Terminal" showLineNumbers={false} +npm create amplify@latest +``` -### 2. Deploy the starter app +Follow the prompts to scaffold your Amplify backend, which copies template files for auth and data resources, and installs required dependencies to your project. The creation flow is intended to be run from the same directory as your frontend project, however it can be executed from any directory. + +This will add the following files to your project's directory: + +```text +├── amplify/ +│ ├── auth/ +│ │ └── resource.ts +│ ├── data/ +│ │ └── resource.ts +│ ├── backend.ts +│ ├── tsconfig.json +│ └── package.json +``` + +If you prefer setting up your project from scratch, refer to the [documentation for manual installation](https://docs.amplify.aws/react/start/manual-installation/). + +## Set up local AWS credentials + +To make backend updates, we are going to require AWS credentials to deploy backend updates from our local machine. + +**Skip ahead**, if you already have an AWS profile with credentials on your local machine, and your AWS profile has the `AmplifyBackendDeployFullAccess` permission policy. + +Otherwise, **[set up local AWS credentials](/[platform]/start/account-setup/)** that grant Amplify permissions to deploy backend updates from your local machine. + +## Deploy cloud sandbox + +To update your backend without affecting the production branch, use Amplify's cloud sandbox. This feature provides a separate backend environment for each developer on a team, ideal for local development and testing. + +To start your cloud sandbox, run the following command in a **new Terminal window**: + +```bash title="Terminal" showLineNumbers={false} +npx ampx sandbox +``` + +Once the cloud sandbox has been fully deployed (~5 min), you'll see the `amplify_outputs.json` file updated with connection information to a new isolated authentication and data backend. + + + +The `npx ampx sandbox` command should run concurrently to your `npm run dev`. You can think of the cloud sandbox as the "localhost-equivalent for your app backend". + + + +## Configure your frontend with Amplify + +Now that your personal cloud sandbox is deployed and connection information is populated, you will need to configure the Amplify library to interact with your backend resources by using the `amplify_outputs.json` file. + +```tsx title="src/main.tsx" +// highlight-next-line +import { Amplify } from "aws-amplify" +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import App from './App.tsx' +// highlight-next-line +import outputs from "../amplify_outputs.json" +import './index.css' + +// highlight-next-line +Amplify.configure(outputs) + +createRoot(document.getElementById('root')!).render( + + + , +) +``` + +By doing so, Amplify will be able to communicate with your backend resources like Auth and Data when you use APIs such as `signIn()` or `generateClient()` without requiring you to pass context manually on each call. + +## Add authentication to your frontend + +Once the Amplify library is configured you are ready to add authentication to your app. The easiest way to get started is by using the [Amplify Authenticator connected component](https://ui.docs.amplify.aws/react/connected-components/authenticator). + +First, install the Amplify UI library for React: + +```bash title="Terminal" showLineNumbers={false} +npm add @aws-amplify/ui-react +``` + +Then, open your `src/App.tsx` file and wrap the existing content with ``. + +```tsx title="src/App.tsx" +// highlight-next-line +import { Authenticator } from '@aws-amplify/ui-react'; +import { useState } from 'react'; +import reactLogo from './assets/react.svg'; +import viteLogo from '/vite.svg'; +// highlight-next-line +import "@aws-amplify/ui-react/styles.css" +import './App.css'; + +function App() { + const [count, setCount] = useState(0); + + return ( + // highlight-next-line + + +

Vite + React

+
+ +

+ Edit src/App.tsx and save to test HMR +

+
+

+ Click on the Vite and React logos to learn more +

+ // highlight-next-line +
+ ); +} + +export default App; +``` + + + +CSS files generated by [`create-vite`](https://www.npmjs.com/package/create-vite) clash with the default styling for Amplify UI. For demo purposes, remove the `index.css` import in `src/main.tsx` + +```tsx title="src/main.tsx" +import { Amplify } from "aws-amplify" +import { StrictMode } from "react" +import { createRoot } from "react-dom/client" +import App from "./App.tsx" +import outputs from "../amplify_outputs.json" +// highlight-next-line +// import "./index.css" + +Amplify.configure(outputs) + +createRoot(document.getElementById("root")!).render( + + + +) +``` + +And remove `text-align: center` from the generated `App.css` file: + +```css title="src/App.css" +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + // highlight-next-line + /* text-align: center; */ +} + +/* ... */ +``` + + + +Lastly, start your frontend's development server by running the `dev` script. + +```bash title="Terminal" showLineNumbers={false} +npm run dev +``` + +Visit [`http://localhost:5173`](http://localhost:5173) to view the changes and create your first user account! + +![Amplify Authenticator component is displayed on a web page](/images/gen2/getting-started/authenticator-localhost-(720p).png) + +By default, Amplify Auth resources are created with email and password login. To learn more about Amplify Auth visit the [documentation for setting up Auth](/[platform]/build-a-backend/auth/set-up-auth). + +## Add data to your frontend + +Now that you have your application's backend deployed, Amplify library configured, and your first user account created, you are ready to begin adding data to your frontend application. Amplify Data is scaffolded at `amplify/data/resource.ts` with a basic `Todo` model which we will use for this example. You define a schema with `a.schema()` that is used to generate a type for the frontend client to use for intellisense and fast iterations. + +Before you make changes to your frontend, open `amplify/data/resource.ts` and modify the default authorization rule to allow owners to create, read, update, and delete their own To-dos. + +```ts title="amplify/data/resource.ts" +// ... +const schema = a.schema({ + Todo: a + .model({ + content: a.string() + }) + // highlight-next-line + .authorization((allow) => [allow.owner()]) +}); + +export type Schema = ClientSchema; + +export const data = defineData({ + schema, + authorizationModes: { + // highlight-start + // change "iam" to "userPool" + defaultAuthorizationMode: 'userPool' + // highlight-end + } +}); +``` + +Then let's revisit your `App.tsx` file to list existing To-dos and create new To-dos. + +```tsx title="src/App.tsx" + +``` + +{/* note about authorization rules and how to change */} +{/* "next step" to set up data page */} + +## Deploy to AWS Now that the repository has been created, deploy it with Amplify. @@ -328,21 +540,20 @@ Let's take a tour of the project structure in this starter repository by opening ```text ├── amplify/ # Folder containing your Amplify backend configuration │ ├── auth/ # Definition for your auth backend -│ │ └── resource.tsx +│ │ └── resource.ts │ ├── data/ # Definition for your data backend │ │ └── resource.ts | ├── backend.ts │ └── tsconfig.json -├── src/ # React UI code -│ ├── App.tsx # UI code to sync todos in real-time -│ ├── index.css # Styling for your app -│ └── main.tsx # Entrypoint of the Amplify client library +│ └── package.json +├── src/ # your React application source code +│ └── ... ├── package.json └── tsconfig.json ``` - When the build completes, visit the newly deployed branch by selecting "Visit deployed URL". Since the build deployed an API, database, and authentication backend, you will be able to create new to-do items. +When the build completes, visit the newly deployed branch by selecting "Visit deployed URL". Since the build deployed an API, database, and authentication backend, you will be able to create new to-do items.