4  Componentes, Dados e Layouts

No capítulo anterior, criamos a página inicial e as páginas Sobre, Equipe e Contato. Embora o site esteja funcional, precisamos repetir o cabeçalho, o menu de navegação e o rodapé em todas as quatro páginas.

Imagine que, no futuro, a TED System precise adicionar um novo link no menu, como “Serviços”. Do jeito que o site está construído, você precisaria abrir os quatro arquivos e alterar o HTML de cada um deles. Isso dá muito trabalho e facilita erros.

Neste capítulo, vamos resolver esse problema criando componentes reutilizáveis, um layout base para as páginas e um arquivo central com todas as informações da empresa.

4.1 Centralizando os Dados da Empresa

A TED System possui textos que aparecem em várias partes do site. Vamos centralizar todas as informações em um único arquivo de dados. Dessa forma, quando o telefone ou o endereço mudar, você altera apenas um arquivo.

  1. No Explorador de Arquivos à esquerda, passe o mouse sobre a pasta src/.
  2. Clique no ícone de Nova Pasta (New Folder).
  3. Escreva o nome data e pressione Enter.
  4. Passe o mouse sobre a nova pasta src/data/ e clique no ícone de Novo Arquivo (New File).
  5. Escreva empresa.js, pressione Enter e adicione o seguinte código:
src/data/empresa.js
export const empresa = {
  nome: "TED System",
  slogan: "Tecnologia que evolui com o seu negócio.",
  historia:
    "Fundada em 2018 na cidade de Piripiri, no Piauí, a TED System nasceu do sonho do engenheiro de software Wanderson de Vasconcelos de aproximar a tecnologia de qualidade das pequenas e médias empresas do interior do Nordeste. O que começou como um projeto de freelancer, desenvolvendo sistemas de gestão para comércios locais, cresceu com a chegada de Sheldon Cooper, especialista em desenvolvimento Full Stack, e de Amy Farrah Fowler, responsável por estruturar e proteger os bancos de dados dos clientes. Hoje, a TED System é uma software house reconhecida pela entrega de soluções sob medida, com foco em qualidade de código, segurança da informação e atendimento próximo aos clientes.",
  missao:
    "Desenvolver soluções de software personalizadas, seguras e escaláveis que simplifiquem processos, aumentem a produtividade e impulsionem o crescimento dos nossos clientes.",
  visao:
    "Ser referência nacional em desenvolvimento de software sob medida até 2030, reconhecida pela excelência técnica, pela inovação constante e pelo impacto positivo gerado nos negócios que atendemos.",
  valores: [
    {
      titulo: "Excelência técnica",
      descricao: "Compromisso com código limpo, boas práticas de engenharia e entregas de alta qualidade."
    },
    {
      titulo: "Transparência e parceria",
      descricao: "Comunicação clara e honesta, tratando cada cliente como um parceiro de longo prazo."
    },
    {
      titulo: "Inovação responsável",
      descricao: "Adoção de novas tecnologias com foco em segurança, sustentabilidade e resultados reais."
    }
  ],
  publicoAlvo:
    "Pequenas e médias empresas (PMEs), startups e profissionais autônomos de diversos segmentos, como comércio, saúde, educação e serviços, que precisam de sistemas web, aplicativos e soluções de gestão personalizadas, além de organizações que buscam modernizar sistemas legados ou melhorar a gestão e a segurança de seus dados.",
  contato: {
    email: "contato@tedsystem.com.br",
    telefone: "(86) 3276-0042",
    endereco: {
      logradouro: "Rua Coronel Simplício, 250",
      complemento: "Sala 12",
      bairro: "Centro",
      cidadeEstado: "Piripiri, PI",
      cep: "64260-000"
    }
  },
  equipe: [
    {
      nome: "Wanderson de Vasconcelos",
      cargo: "CEO e Engenheiro de Software",
      foto: "/images/wanderson.jpg",
      alt: "Foto de Wanderson de Vasconcelos",
      descricao: "Fundador da TED System, começou desenvolvendo sistemas de gestão para comércios locais do interior do Nordeste."
    },
    {
      nome: "Sheldon Cooper",
      cargo: "Especialista Full Stack",
      foto: "/images/sheldon.jpg",
      alt: "Foto de Sheldon Cooper",
      descricao: "Especialista em desenvolvimento Full Stack, chegou para ampliar a capacidade de entrega da empresa."
    },
    {
      nome: "Amy Farrah Fowler",
      cargo: "Especialista em Bancos de Dados",
      foto: "/images/amy.jpg",
      alt: "Foto de Amy Farrah Fowler",
      descricao: "Responsável por estruturar e proteger os bancos de dados dos clientes."
    }
  ]
};

Pressione Ctrl + S (ou Cmd + S no Mac) para salvar.

Neste arquivo, usamos recursos fundamentais do JavaScript moderno:

  • export: Permite que esta informação seja importada e utilizada em outros arquivos do projeto.
  • Objetos: Estruturam informações em pares de “nome” e “valor” dentro de chaves { }, como nome: "TED System". Objetos podem conter outros objetos, como visto em contato e endereco.
  • Listas (Arrays): Coleções de itens dentro de colchetes [ ]. Usamos listas para organizar os valores e a equipe da empresa. Os campos foto e alt preparam as informações para as imagens que usaremos no capítulo 5.

4.2 Criando o Cabeçalho e o Rodapé

Com os dados prontos, vamos extrair o cabeçalho e o rodapé que se repetem nas quatro páginas e transformá-los em Componentes Astro. Componentes são pequenos blocos de construção que podem ser reutilizados em qualquer lugar.

  1. No Explorador de Arquivos, passe o mouse sobre a pasta src/.
  2. Clique no ícone de Nova Pasta (New Folder).
  3. Escreva components e pressione Enter.
  4. Passe o mouse sobre src/components/ e clique no ícone de Novo Arquivo (New File).
  5. Escreva Header.astro, pressione Enter e adicione o seguinte código:
src/components/Header.astro
---
import { empresa } from '../data/empresa.js';
---

<header>
	<strong><a href="/">{empresa.nome}</a></strong>
	<nav>
		<ul>
			<li><a href="/">Início</a></li>
			<li><a href="/sobre">Sobre</a></li>
			<li><a href="/equipe">Equipe</a></li>
			<li><a href="/contato">Contato</a></li>
		</ul>
	</nav>
</header>

Salve o arquivo pressionando Ctrl + S (ou Cmd + S no Mac).

No Astro, nós usamos chaves { } para inserir variáveis JavaScript diretamente no HTML (chamado de Expressões no Template). A instrução import { empresa } puxa os dados que acabamos de criar, e a expressão {empresa.nome} exibe o texto “TED System” como um link para a página inicial.

Você notou que o nome do arquivo Header.astro (e mais tarde o LayoutBase.astro) começa com letra maiúscula? Isso é uma convenção. A exigência está no nome usado no código: segundo a documentação oficial do Astro, o nome de um componente precisa começar com letra maiúscula, como <Header />; com letra minúscula, como <header>, o Astro o trata como uma tag HTML comum. Por isso, é comum dar ao arquivo o mesmo nome do componente, com iniciais maiúsculas (PascalCase). Já as páginas na pasta src/pages/ usam letras minúsculas (sobre.astro) porque o nome do arquivo se transforma diretamente no endereço do site (/sobre), e endereços web são tradicionalmente minúsculos.

4.3 Criando o Layout Base

Além do cabeçalho e do rodapé, a estrutura principal de uma página HTML (como <html>, <head>, <meta>, e <body>) se repete. No Astro, usamos um Layout para fornecer esse esqueleto comum a todas as páginas.

  1. No Explorador de Arquivos, passe o mouse sobre a pasta src/.
  2. Clique no ícone de Nova Pasta (New Folder).
  3. Escreva layouts e pressione Enter.
  4. Passe o mouse sobre src/layouts/ e clique no ícone de Novo Arquivo (New File).
  5. Escreva LayoutBase.astro, pressione Enter e adicione o código:
src/layouts/LayoutBase.astro
---
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
import { empresa } from '../data/empresa.js';

const { titulo, descricao } = Astro.props;
---

<html lang="pt-BR">
	<head>
		<meta charset="utf-8" />
		<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<meta name="description" content={descricao} />
		<title>{titulo} | {empresa.nome}</title>
	</head>
	<body>
		<Header />
		<main>
			<slot />
		</main>
		<Footer />
	</body>
</html>

Salve o arquivo pressionando Ctrl + S (ou Cmd + S no Mac).

O bloco delimitado por --- no início do arquivo .astro é chamado de frontmatter. Ele retornou! É nele que você escreve o JavaScript necessário para preparar os dados antes que o HTML seja construído. Neste arquivo, vemos dois conceitos importantes:

  • Props (Astro.props): Permitem que uma página passe informações específicas para o layout. Cada página fornecerá seu próprio titulo e uma descricao para a tag <meta name="description"> (útil para os mecanismos de busca).
  • <slot />: Funciona como um espaço reservado. É exatamente na posição do <slot /> que o Astro vai injetar o conteúdo exclusivo de cada página (como os textos sobre a empresa ou a lista da equipe).
Explorador de arquivos com a pasta src contendo components (Footer.astro e Header.astro), data (empresa.js), layouts (LayoutBase.astro) e pages (contato.astro, equipe.astro, index.astro e sobre.astro).
Figura 4.1: Estrutura da pasta src após as alterações

4.4 Refatorando as Páginas

Agora vamos atualizar as nossas quatro páginas para usar o LayoutBase.

4.4.1 Página Inicial

Abra src/pages/index.astro e substitua todo o conteúdo por:

src/pages/index.astro
---
import LayoutBase from '../layouts/LayoutBase.astro';
import { empresa } from '../data/empresa.js';
---

<LayoutBase 
	titulo="Início" 
	descricao={`Bem-vindo à ${empresa.nome}. ${empresa.slogan}`}
>
	<section>
		<h1>{empresa.slogan}</h1>
		<p>{empresa.missao}</p>
		<a href="/contato">Fale Conosco</a>
	</section>

	<section>
		<h2>Quem Atendemos</h2>
		<p>{empresa.publicoAlvo}</p>
	</section>
</LayoutBase>

Salve o arquivo pressionando Ctrl + S (ou Cmd + S no Mac). Veja como a página ficou curta! Todo o esqueleto HTML repetitivo foi substituído pelo componente <LayoutBase>. Note também que a descrição agora usa o mesmo recurso de textos com variáveis entre crases visto no rodapé.

4.4.2 Página Sobre

Abra src/pages/sobre.astro e atualize para:

src/pages/sobre.astro
---
import LayoutBase from '../layouts/LayoutBase.astro';
import { empresa } from '../data/empresa.js';
---

<LayoutBase 
	titulo="Sobre Nós" 
	descricao={`Conheça a história e os valores da ${empresa.nome}.`}
>
	<section>
		<h1>Sobre a {empresa.nome}</h1>
		<p>{empresa.historia}</p>
	</section>

	<section>
		<h2>Missão</h2>
		<p>{empresa.missao}</p>
	</section>

	<section>
		<h2>Visão</h2>
		<p>{empresa.visao}</p>
	</section>

	<section>
		<h2>Nossos Valores</h2>
		<ul>
			{empresa.valores.map((valor) => (
				<li>
					<h3>{valor.titulo}</h3>
					<p>{valor.descricao}</p>
				</li>
			))}
		</ul>
	</section>
</LayoutBase>

Salve o arquivo pressionando Ctrl + S (ou Cmd + S no Mac).

A função map() é muito utilizada no Astro. Ela percorre a lista de valores que definimos no empresa.js e, para cada item, gera automaticamente um bloco HTML <li>. Se um dia você adicionar um novo valor à empresa, o site o exibirá automaticamente, sem que você precise mexer no código da página.

Dica

O poder do .map() no Astro O método .map() é adequado para transformar listas de dados puros (como os valores da empresa em JavaScript) em elementos HTML repetitivos. Isso automatiza a construção visual e elimina a necessidade de “copiar e colar” código.

4.4.3 Página Equipe

Abra src/pages/equipe.astro e atualize para:

src/pages/equipe.astro
---
import LayoutBase from '../layouts/LayoutBase.astro';
import { empresa } from '../data/empresa.js';
---

<LayoutBase 
	titulo="Nossa Equipe" 
	descricao={`Conheça os profissionais por trás da ${empresa.nome}.`}
>
	<section>
		<h1>Nossa Equipe Técnica</h1>
		<p>Conheça os profissionais que transformam requisitos de negócio em soluções de software seguras e escaláveis</p>
		<ul>
			{empresa.equipe.map((membro) => (
				<li>
					<h2>{membro.nome}</h2>
					<strong>{membro.cargo}</strong>
					<p>{membro.descricao}</p>
				</li>
			))}
		</ul>
	</section>
</LayoutBase>

Salve o arquivo pressionando Ctrl + S (ou Cmd + S no Mac). A lista de equipe também foi construída usando o .map().

4.4.4 Página Contato

Abra src/pages/contato.astro e atualize para:

src/pages/contato.astro
---
import LayoutBase from '../layouts/LayoutBase.astro';
import { empresa } from '../data/empresa.js';
---

<LayoutBase 
	titulo="Fale Conosco" 
	descricao={`Entre em contato com a ${empresa.nome}.`}
>
	<section>
		<h1>Fale Conosco</h1>
		<p>Deseja construir uma solução de software sob medida para o seu negócio? Entre em contato com a {empresa.nome}!</p>
	</section>

	<section>
		<h2>Nossa Sede</h2>
		<address>
			{empresa.contato.endereco.logradouro}, {empresa.contato.endereco.complemento}<br />
			{empresa.contato.endereco.bairro}<br />
			{empresa.contato.endereco.cidadeEstado}<br />
			CEP: {empresa.contato.endereco.cep}
		</address>
	</section>

	<section>
		<h2>Canais Digitais</h2>
		<p><strong>E-mail:</strong> <a href={`mailto:${empresa.contato.email}`}>{empresa.contato.email}</a></p>
		<p><strong>Telefone:</strong> {empresa.contato.telefone}</p>
	</section>
</LayoutBase>

Salve o arquivo pressionando Ctrl + S (ou Cmd + S no Mac).

4.5 Testando e Verificando

Vamos testar o projeto para confirmar que tudo funciona, agora com os componentes integrados.

Inicie o servidor de desenvolvimento:

npm run dev

Abra a aba Portas (Ports), passe o mouse sobre o endereço na coluna Endereço Encaminhado (Forwarded Address) e clique no ícone do globo, Abrir no Navegador (Open in Browser). Navegue pelas páginas (Início, Sobre, Equipe e Contato).

Página Início sem estilos, com o nome TED System como link, o menu, o conteúdo da página e o novo rodapé com endereço, e-mail e telefone.
Figura 4.2: Visualização da aba Início
Página Sobre Nós sem estilos, com a história, a missão, a visão, os valores e o novo rodapé da empresa.
Figura 4.3: Visualização da aba Sobre Nós
Página Nossa Equipe sem estilos, com os três profissionais e o novo rodapé da empresa.
Figura 4.4: Visualização da aba Nossa Equipe
Página Fale Conosco sem estilos, com o endereço, os canais digitais e o novo rodapé da empresa.
Figura 4.5: Visualização da aba Fale Conosco

Você verá o mesmo conteúdo de antes, mas o rodapé agora exibe as informações completas de contato e o ano atual. Observe também os títulos das abas do navegador, que agora refletem a página atual graças ao LayoutBase. E o mais importante: se precisarmos mudar o menu no futuro, faremos isso em apenas um lugar!

Para encerrar o servidor, volte ao terminal e pressione Ctrl + C.

Por fim, execute o processo de construção para garantir que o código que escrevemos não possui erros que impeçam a geração do site estático:

npm run build

Na saída final, observe a mensagem indicando a criação das quatro páginas (4 page(s) built in ...).

4.6 Registrando o Progresso no Git

Registre suas melhorias no Git executando a sequência de comandos abaixo no terminal.

4.6.1 Verificando os arquivos modificados com git status

git status

O Git mostrará que você criou as pastas data, components e layouts, e alterou as quatro páginas na pasta pages.

4.6.2 Adicionando as mudanças com git add

git add .

4.6.3 Criando o commit descritivo com git commit

git commit -m "feat: centraliza os dados e cria o layout, o cabeçalho e o rodapé"

4.6.4 Sincronizando com o repositório remoto com git push

git push

4.7 Resumo e Próximos Passos

Você atingiu um marco essencial: o site da TED System agora é modular e dinâmico, utilizando a arquitetura de componentes do Astro!

Neste capítulo, você aprendeu:

  • Como isolar os textos da empresa em um arquivo de dados JavaScript (src/data/empresa.js) usando as instruções export e import;
  • Como injetar variáveis JavaScript dinamicamente no HTML utilizando expressões entre chaves ({ });
  • O que são as Funções de Array do JavaScript, como o .map(), que permite percorrer listas para construir elementos repetitivos;
  • Como compor textos com variáveis utilizando crases (Template Literals);
  • A aplicar métodos nativos como new Date().getFullYear() para obter o ano atual de forma programática;
  • Como o sistema de props (propriedades) e a tag especial <slot /> permitem criar um Layout Base dinâmico (LayoutBase.astro);
  • A fracionar o projeto criando componentes de cabeçalho (Header.astro) e rodapé (Footer.astro).

No próximo capítulo, aplicaremos estilos visuais em CSS, incluiremos as imagens no projeto, criaremos um componente de cartão (Cartao.astro) para exibir os valores da empresa e adicionaremos a lógica de menu ativo. Até lá!