Pular para o conteúdo

React Website

Este gerador cria um novo site React com shadcn/ui configurado por padrão, juntamente com a infraestrutura AWS CDK ou Terraform para implantar seu site na nuvem como um site estático hospedado no S3, servido pelo CloudFront e protegido pelo WAF.

A aplicação gerada usa Vite como ferramenta de build e bundler. Ela usa TanStack Router para roteamento type-safe.

Você pode gerar um novo React Website de duas maneiras:

Execute este gerador@aws/nx-plugin:ts#website

pnpm nx g @aws/nx-plugin:ts#website
Monte seu comando10

Obrigatório

Opções do gerador10 opções
nameObrigatóriostring

O nome da aplicação.

frameworkenumPadrão: react

O framework frontend a ser usado.

react
directorystringPadrão: packages

O diretório da nova aplicação.

uxenumPadrão: shadcn

O provedor de UX preferido.

nonecloudscapeshadcn
tailwindbooleanPadrão: true

Ativar TailwindCSS para estilização utility-first.

tanstackRouterbooleanPadrão: true

Ativar roteador Tanstack para roteamento type-safe.

infraenumPadrão: cloudfront-s3

O tipo de infraestrutura para implantar seu website.

cloudfront-s3none
iacenumPadrão: inherit

O provedor de IaC preferido. Por padrão, este é herdado da sua seleção inicial.

inheritcdkterraform
subDirectorystring

O subdiretório onde o projeto é colocado. Por padrão, este é o nome do projeto.

preferInstallDependenciesbooleanPadrão: true

Se deve preferir instalar dependências após a execução do gerador. Defina como false para adiar a instalação ao executar múltiplos geradores em lote (uma instalação ainda é executada se necessário para que geradores subsequentes possam calcular o grafo de projetos Nx); instale uma vez no final.

O gerador criará a seguinte estrutura de projeto no diretório <directory>/<name>:

  • index.html HTML entry point
  • public Static assets
  • Directorysrc
    • main.tsx Application entry point with React setup
    • config.ts Application configuration (eg. logo)
    • Directorycomponents
      • AppLayout Components for the overall layout and navigation bar
      • app-sidebar.tsx Sidebar navigation (shadcn only)
      • alert.tsx Alert component wrapping your UX provider’s own
      • spinner.tsx Spinner component wrapping your UX provider’s own
    • Directoryhooks
      • useAppLayout.tsx Hook for adjusting the AppLayout from nested components (Cloudscape only)
    • Directoryroutes
      • __root.tsx Root route, wrapping every page in the AppLayout
      • index.tsx Example route (or page) for TanStack Router
    • routeTree.gen.ts Route tree, generated and maintained by TanStack Router
    • styles.css Global styles
  • vite.config.mts Vite and Vitest configuration
  • project.json Nx project defining the project’s targets
  • tsconfig.json Base TypeScript configuration for source and tests
  • tsconfig.app.json TypeScript configuration for source code
  • tsconfig.spec.json TypeScript configuration for tests
  • package.json Project manifest defining the project’s package name and dependencies
  • README.md Project README

Como este gerador fornece infraestrutura como código baseada no seu iac escolhido, ele criará um projeto em packages/common que inclui os constructs CDK relevantes ou módulos Terraform.

O projeto comum de infraestrutura como código é estruturado da seguinte forma:

  • Directorypackages/common/constructs
    • Directorysrc
      • Directoryapp/ Constructs for infrastructure specific to a project/generator
      • Directorycore/ Generic constructs which are reused by constructs in app
      • index.ts Entry point exporting constructs from app
    • project.json Project build targets and configuration

O gerador cria infraestrutura como código para implantar seu site com base no iac selecionado:

  • Directorypackages/common/constructs/src
    • Directoryapp
      • Directorystatic-websites
        • <name>.ts Infrastructure specific to your website
    • Directorycore
      • static-website.ts Generic StaticWebsite construct

O site implantado tem a seguinte arquitetura: seus assets construídos em um bucket S3, servidos por uma distribuição CloudFront com um AWS WAFv2 Web ACL na frente dele.

Loading the diagram…

A documentação do React é um bom lugar para começar a aprender os conceitos básicos de construção com React.

ux = cloudscape

Você pode consultar a documentação do Cloudscape para detalhes sobre os componentes disponíveis e como usá-los.

ux = shadcn

Você pode consultar a documentação do shadcn/ui para detalhes sobre os componentes disponíveis e como usá-los.

Seu site vem com TanStack Router configurado por padrão. Isso facilita a adição de novas rotas:

  1. Execute o Servidor de Desenvolvimento Local
  2. Crie um novo arquivo <page-name>.tsx em src/routes, com sua posição na árvore de arquivos representando o caminho
  3. Observe que um Route e RouteComponent são gerados automaticamente para você. Você pode começar a construir sua página aqui!

Você pode usar o componente Link ou o hook useNavigate para navegar entre páginas:

import { Link, useNavigate } from '@tanstack/react-router';
export const MyComponent = ({
createProduct,
}: {
createProduct: () => Promise<string>;
}) => {
const navigate = useNavigate();
const submit = async () => {
const id = await createProduct();
// Use `navigate` for redirecting after some asynchronous action
navigate({ to: '/products/$id', params: { id } });
};
return (
<>
<Link to="/products">Cancel</Link>
<button onClick={submit}>Submit</button>
</>
);
};

$id in the to path is a path parameter, supplied through params. Swap the plain <button> for your UX kit’s own button component as needed.

Para mais detalhes, confira a documentação do TanStack Router.

O gerador de site React cria infraestrutura como código CDK ou Terraform com base no iac selecionado. Você pode usar isso para implantar seu site.

Para implantar seu site, recomendamos usar o gerador ts#infra para criar uma aplicação CDK.

Você pode usar o construct CDK gerado para você em packages/common/constructs para implantar seu site.

packages/infra/src/stacks/application-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { MyWebsite } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
new MyWebsite(this, 'MyWebsite');
}
}

Isso configura:

  1. Um bucket S3 para hospedar seus arquivos de site estático
  2. Distribuição CloudFront para entrega global de conteúdo
  3. WAF Web ACL para proteção de segurança
  4. Origin Access Control para acesso seguro ao S3
  5. Implantação automática de arquivos do site e configuração de runtime

A distribuição CloudFront aplica uma política de cabeçalhos de resposta que define Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options: DENY, Referrer-Policy e uma Content-Security-Policy em todas as respostas.

Uma Content-Security-Policy padrão é aplicada. Ela restringe scripts e framing para mitigar XSS e clickjacking, enquanto permite conexões HTTPS e WSS para que o site possa chamar endpoints de serviços AWS (como API Gateway, Cognito e Bedrock AgentCore) cujas URLs são conhecidas apenas no momento da implantação. Para ajustar a política (por exemplo, para restringir connect-src às suas origens específicas), edite o valor content_security_policy no seu static-website.ts (CDK) ou static-website.tf (Terraform) gerado.

runtime-config.json é servido com Cache-Control: no-cache para que os navegadores sempre busquem a configuração mais recente após uma reimplantação, em vez de usar uma cópia em cache desatualizada.

A distribuição CloudFront é protegida por um AWS WAFv2 Web ACL por padrão. O Web ACL usa o conjunto de regras padrão gerenciado pela AWS (AWSManagedRulesCommonRuleSet e AWSManagedRulesKnownBadInputsRuleSet), fornecendo proteção contra explorações web comuns, incluindo o OWASP Top 10.

Para desativar, defina enableWaf como false ao criar seu site:

packages/infra/src/stacks/application-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { MyWebsite, suppressRules } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const website = new MyWebsite(this, 'MyWebsite', {
enableWaf: false,
});
// Disabling WAF fails the checkov CKV_AWS_68 check ("CloudFront
// Distribution should have WAF enabled"). Suppress it explicitly.
suppressRules(
website.cloudFrontDistribution,
['CKV_AWS_68'],
'WAF is intentionally disabled for this distribution',
);
}
}

O bucket do site, o bucket de log da distribuição CloudFront e o grupo CloudWatch Logs que recebe seus logs de acesso ao servidor são criptografados com uma chave AWS KMS gerenciada pelo cliente por padrão. Esta chave é criada automaticamente para você, com rotação de chave habilitada.

Se você quiser usar uma configuração de criptografia diferente, passe as props encryption, encryptionKey e enableKeyRotation ao criar seu site:

packages/infra/src/stacks/application-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { BucketEncryption } from 'aws-cdk-lib/aws-s3';
import { MyWebsite } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
new MyWebsite(this, 'MyWebsite', {
encryption: BucketEncryption.S3_MANAGED,
});
}
}

Para usar sua própria chave KMS em vez de uma criada automaticamente, passe encryptionKey:

new MyWebsite(this, 'MyWebsite', {
encryptionKey: myKey,
});

enableKeyRotation (padrão true) só se aplica à chave criada automaticamente, ou seja, quando encryption é BucketEncryption.KMS (o padrão) e nenhum encryptionKey é fornecido:

new MyWebsite(this, 'MyWebsite', {
enableKeyRotation: false,
});

Por padrão, a distribuição usa o nome de domínio padrão do CloudFront (*.cloudfront.net) e seu certificado padrão, que não suporta a aplicação de uma versão TLS mínima de 1.2. Para servir seu site a partir do seu próprio domínio, forneça um certificado ACM (que deve residir em us-east-1 para uso com CloudFront) e seus nomes de domínio. Uma versão TLS mínima de 1.2 é então aplicada para os visualizadores:

Passe as props certificate e domainNames ao criar seu site:

packages/infra/src/stacks/application-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Certificate } from 'aws-cdk-lib/aws-certificatemanager';
import { MyWebsite } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
new MyWebsite(this, 'MyWebsite', {
domainNames: ['www.example.com'],
certificate: Certificate.fromCertificateArn(this, 'Cert',
'arn:aws:acm:us-east-1:123456789012:certificate/...'),
});
}
}

Você também precisará criar registros DNS (por exemplo, no Route 53) apontando seu domínio para a distribuição CloudFront.

A configuração da sua infraestrutura é fornecida ao seu site via Configuração de Runtime. Isso permite que seu site acesse detalhes como URLs de API que não são conhecidas até que sua aplicação seja implantada.

O construct CDK RuntimeConfig pode ser usado para adicionar e recuperar configuração em sua infraestrutura CDK. Os constructs CDK gerados pelos geradores @aws/nx-plugin (como ts#api e py#api) adicionarão automaticamente valores apropriados ao RuntimeConfig.

Seu construct CDK de site implantará o namespace connection da configuração de runtime como um arquivo runtime-config.json na raiz do seu bucket S3.

packages/infra/src/stacks/application-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { MyWebsite, MyApi } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Website can be declared at any point, since runtime config is resolved lazily
new MyWebsite(this, 'MyWebsite');
// Automatically adds values to the RuntimeConfig
new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
});
}
}

No seu site, você pode usar o hook useRuntimeConfig para recuperar valores da configuração de runtime:

import { useRuntimeConfig } from '../hooks/useRuntimeConfig';
const MyComponent = () => {
const runtimeConfig = useRuntimeConfig();
// Access values in the runtime config here
const apiUrl = runtimeConfig.apis.MyApi;
};

Ao executar o servidor de desenvolvimento local, você precisará de um arquivo runtime-config.json no seu diretório public para que seu site local conheça as URLs de backend, configuração de identidade, etc.

Seu projeto de site está configurado com um target load-runtime-config que você pode usar para baixar o arquivo runtime-config.json de uma aplicação implantada:

Terminal window
pnpm nx load-runtime-config <my-website>

O comando canônico para desenvolvimento local é dev, que inicia seu site (e quaisquer servidores locais para APIs que você conectou a ele) com um único comando:

Terminal window
pnpm nx dev <my-website>

O target serve também está disponível para quando você precisa controlar quanto da sua aplicação é executado localmente versus apontando para infraestrutura AWS implantada. Para uma visão geral mais ampla do desenvolvimento local em projetos conectados, incluindo como dev se comporta para projetos com múltiplos componentes, consulte o guia Desenvolvimento Local.

O target serve inicia um servidor de desenvolvimento local para seu site. Este target requer que você tenha implantado qualquer infraestrutura de suporte com a qual o site interage e tenha carregado a configuração de runtime local.

Você pode executar este target com o seguinte comando:

Terminal window
pnpm nx serve <my-website>

Este target é útil para trabalhar em alterações do site enquanto aponta para APIs “reais” implantadas e outra infraestrutura.

O target dev inicia um servidor de desenvolvimento local para seu site (com Vite MODE definido como local-dev), bem como inicia quaisquer servidores locais para APIs que você conectou ao seu site via o gerador Connection.

Quando seu servidor de site local é executado via este target, runtime-config.json é automaticamente substituído para apontar para suas URLs de API em execução local.

Você pode executar este target com o seguinte comando:

Terminal window
pnpm nx dev <my-website>

Este target é útil quando você está trabalhando em seu site e API e deseja iterar rapidamente sem implantar sua infraestrutura.

Autenticação Simulada

Quando executado neste modo e nenhum runtime-config.json está presente, se você configurou Autenticação Cognito (via o gerador ts#website#auth), o login será ignorado e as solicitações aos seus servidores locais não incluirão cabeçalhos de autenticação.

Para habilitar login e autenticação para dev, implante sua infraestrutura e carregue a configuração de runtime.

Você pode fazer o build do seu site usando o target build. Isso executa os targets bundle, compile, test e lint, fazendo verificação de tipos, bundling, testes e linting do seu site.

Terminal window
pnpm nx build <my-website>

O target bundle usa Vite para criar um bundle de produção no diretório raiz dist/packages/<my-website>/bundle. Este é o artefato implantável consumido pela sua infraestrutura de site. Você pode executá-lo sozinho:

Terminal window
pnpm nx bundle <my-website>

Testar seu site é muito parecido com escrever testes em um projeto TypeScript padrão, então consulte o guia de projeto TypeScript para mais detalhes.

Para testes específicos do React, React Testing Library já está instalado e disponível para você usar para escrever testes. Para mais detalhes sobre seu uso, consulte a documentação do React Testing Library.

Você pode executar seus testes usando o target test:

Terminal window
pnpm nx test <my-website>

Use o gerador connection para integrar este projeto com outros no seu workspace. As seguintes conexões envolvem este projeto:

tRPC
React to tRPCCall a tRPC API from a React website
FastAPI
React to FastAPICall a Python FastAPI from a React website
Smithy
React to Smithy APICall a Smithy API from a React website
Strands AgentsPython
React to Python AgentCall a Python Agent from a React website
Strands AgentsTypeScript
React to TypeScript AgentCall a TypeScript Agent from a React website
CopilotKit
React to AG-UI AgentCall an Agent exposing the AG-UI protocol from a React website via CopilotKit
Amazon Bedrock AgentCore Gateway
React Website to AgentCore GatewayConnect a React website to agents through an AgentCore Gateway