🎞️ Slides 📝 Material ← Módulo
Módulo 2 · Ciclo Comum · IN02 Plano de Ensino

Aula 7 — Front-End I · HTML, DOM e JS no SSR + EJS

Plano operacional do dia: o usuário entra na tela — configurar EJS, dominar SSR, escrever HTML semântico e manipular DOM com JS vanilla reusando os controllers do back-end.

← Voltar ao Módulo

Identificação

Disciplina
IN02 · Desenvolvimento Web
Módulo
2 — Ciclo Comum
Aula
7 de 11
Carga horária do dia
6h (2h + 2h + 2h)
Modalidade
Presencial · Metodologia ativa
Pré-aula
Autoestudo guiado
Entrega individual
Desafio — Tela do Projeto em EJS
Entrega em grupo
+1 tela SSR no projeto

Resumo

A aula 7 traz o usuário para a tela. O back-end ganha EJS como view engine; o controller passa a usar res.render('users/index', { users }). Os alunos aprendem SSR vs CSR, sintaxe EJS (<%= %>, <%- %>, <% %>, include), HTML semântico, DOM básico (querySelector, addEventListener, classList) e forms tradicionais com express.urlencoded.

A camada de Views ganha vida — services e repositories da aula 6 são reusados sem alteração; só a forma como o resultado vira tela muda. Validação dupla (cliente + servidor) entra como base de UX e segurança.

Objetivos de aprendizagem

  • OA-1Diferenciar SSR de CSR e justificar a escolha SSR para o projeto.
  • OA-2Configurar EJS no Express e organizar views/ com partials/ e layouts/.
  • OA-3Compor templates EJS com tags de output, controle e include.
  • OA-4Renderizar via controller (res.render) reusando services e repositories já criados.
  • OA-5Aplicar HTML semântico (header, nav, main, section, article, footer).
  • OA-6Manipular DOM e eventos com JS vanilla; aplicar validação dupla (cliente + servidor).

Pré-requisitos

  • Aulas 5 e 6 concluídas: back-end com endpoints CRUD funcionais e testados.
  • Camada de services e repositories isolada (controllers chamam services, não escrevem SQL).
  • EJS instalado no projeto (npm i ejs) — feito no autoestudo.

Cronograma do dia

📚 Bloco 1 · Autoestudo

08h00 — 10h00

Estudo individual orientado pelo material da aula 7.

  • Leitura completa do Material da Aula 7 (SSR vs CSR, EJS, HTML semântico, DOM básico).
  • Esboçar wireframe de 2 telas do projeto integrador (papel ou Figma rápido) — entregar a foto na daily.
  • Instalar EJS no projeto: npm i ejs.
  • Caderno de bordo: anotar dúvidas sobre o porquê de SSR no projeto.

🎓 Bloco 2 · Instrução PE — Aula em metodologia ativa

10h00 — 12h00

Encontro síncrono com o professor especialista. 15 minutos de daily seguidos de 1h45 de aula.

  • 10h00 — 10h15 · Daily: wireframes apresentados em 1 minuto cada.
  • 10h15 — 12h00 · SSR vs CSR, setup EJS, partials, forms tradicionais, DOM básico, segurança XSS.

🍴 Intervalo · Almoço

12h00 — 14h00

Janela livre.

🛠️ Bloco 3 · Desenvolvimento — Desafio individual + projeto em grupo

14h00 — 16h00

14h00 — 14h40 · Desafio individual (warm-up). Cada aluno entrega uma tela do wireframe de alta fidelidade do projeto em EJS antes de voltar ao trabalho em grupo. A entrega valida que a sintaxe EJS, partials, layout e HTML semântico foram dominados de forma autônoma — e adianta uma tela real do produto.

  • Escolher uma tela já desenhada no wireframe de alta fidelidade (Figma) e replicá-la em EJS — sem inventar tela nova.
  • Rota GET dedicada renderizando dados via res.render; dados mockados no controller (objeto/array) — sem hardcode no template.
  • Layout em views/layouts/main.ejs + partials header.ejs e footer.ejs.
  • HTML semântico (<header>, <main>, <section>, <article>) e CSS via public/css/.
  • Branch aula-7-tela-projeto no repositório do projeto + print da página renderizada lado a lado com o wireframe no canal da turma.

14h40 — 16h00 · Projeto integrador (em grupo). Equipe consolida o que cada um trouxe individualmente e fecha a entrega do dia.

  • Integrar as telas individuais ao projeto e adicionar +1 tela SSR reusando os services existentes (mínimo: as telas individuais + 1 tela colaborativa).
  • Consolidar pelo menos 1 partial (header.ejs ou footer.ejs) reaproveitado entre as telas.
  • Form tradicional com express.urlencoded persistindo dado real (POST → controller → service → repository).
  • Pelo menos 1 interação DOM em JS vanilla (toggle de menu, tema, lista, etc.).
  • Abrir Merge Request feat(views): telas SSR com evidência de execução.

Detalhamento da instrução PE (10h00 — 12h00)

10h00
10h15

DailyDaily de abertura

Cada aluno apresenta, em 1 minuto, o wireframe de uma das telas que vai implementar à tarde — defendendo por que SSR resolve melhor que CSR no caso.

10h15
10h35

TalkSSR vs CSR vs hydration

Quadro com os 3 modelos. Critérios: SEO, time-to-first-byte, complexidade de stack, latência percebida. Por que SSR é o caminho natural quando o back-end já existe e o foco é fluxo de dados, não interatividade rica.

10h35
10h55

CodingSetup EJS + primeira home.ejs

Coding ao vivo: app.set('view engine', 'ejs'), app.set('views', ...), criação de views/home.ejs e res.render('home', { titulo: 'Olá' }). Refresh no browser, primeira tela renderizada.

10h55
11h15

AtivaRefatorar HTML em partials

Em pares: separar header.ejs e footer.ejs de home.ejs usando <%- include('partials/header') %>. Debate sobre quando vale partial e quando o include só esconde acoplamento.

11h15
11h35

CodingForm tradicional com urlencoded

Coding em pares: <form method="POST" action="/recurso">, middleware app.use(express.urlencoded({ extended: true })), controller recebendo req.body, chamando o mesmo service da aula 6 e fazendo res.redirect. Discussão sobre PRG (POST-Redirect-GET).

11h35
11h50

CodingDOM básico — querySelector, addEventListener, classList

Adicionar um botão de toggle (menu mobile, tema dark/light ou lista expansível). 10 linhas de JS vanilla, sem framework. Discussão sobre quando isso seria over-engineered como CSR.

11h50
12h00

AtivaSíntese + segurança XSS + anúncio do desafio

Cada aluno escreve em 30 segundos: "<%= %> escapa, <%- %> não". Demo de XSS injection mostrando por que NUNCA usar <%- %> com conteúdo de usuário. Anúncio das duas entregas da tarde: (1) Desafio individual — Tela do Projeto em EJS (14h00 — 14h40, uma tela do wireframe por aluno) e (2) Projeto em grupo — integração + 1 tela adicional + form + DOM + MR.

Estratégias de metodologia ativa

  • Pair programming nos templates — um aluno pensa em estrutura semântica (main, section) enquanto o outro escreve as tags EJS, alternando a cada partial.
  • Debate "quando CSR faz sentido" — provocação coletiva forçando os alunos a defender a escolha SSR no projeto e mapear cenários onde SSR perde.
  • Revisão cruzada de HTML semântico — pares trocam telas e auditam uso de div vs section/article; quem mais reduz div sem perder estrutura ganha simbolicamente.

Desafio individual · Tela do Projeto em EJS

Exercício de aplicação individual e obrigatório, executado na primeira meia hora do bloco de desenvolvimento (14h00 — 14h40). Funciona como warm-up controlado antes do trabalho em equipe e como verificação rápida de que cada aluno dominou autonomamente a sintaxe EJS, a composição com partials e a separação controller/template — replicando uma tela já desenhada no wireframe de alta fidelidade do projeto.

Requisito

  • Escolher uma tela do wireframe de alta fidelidade do projeto (listagem, detalhe ou formulário) e replicá-la em EJS — sem inventar tela nova.
  • Rota GET dedicada (ex.: GET /produtos, GET /pedidos/:id) renderizando a view via res.render('recurso/index', { ... }).
  • Fidelidade visual ao wireframe: hierarquia, blocos, ordem dos elementos e conteúdo. Pixel-perfect fica para a Aula 10 (CSS).

Restrições técnicas

  • Dados em um controller (mock object/array do próprio aluno) — sem hardcode no template.
  • Layout em views/layouts/main.ejs com partials header.ejs + footer.ejs.
  • HTML semântico: <header>, <main>, <section>, <article>.
  • CSS em public/css/ servido via express.static.
  • Sem framework de front (nada de React/Vue/Svelte) e sem fetch — só SSR puro.

Bônus (opcional)

  • Toggle dark mode usando classList.toggle.
  • Route param real (ex.: /produtos/:id) buscando no array mockado.
  • Botão "Imprimir" com window.print().
  • Filtro/busca client-side em JS vanilla sobre dados já renderizados.

Entrega

  • Branch aula-7-tela-projeto no repositório do projeto integrador.
  • Print da página renderizada lado a lado com o wireframe de origem compartilhado no canal da turma.
  • Prazo: até as 14h40 — o restante do bloco é dedicado à integração em grupo.
Por que esse desafio

Cada aluno assume uma tela do wireframe já validado pelo grupo. Isso distribui o trabalho da camada de Views entre os integrantes, garante que ninguém termine a aula sem ter materializado SSR + partials + HTML semântico sozinho, e adianta telas reais do produto — em vez de um exercício descartável.

Recursos e ferramentas

CategoriaRecursoUso
Slidesslides/slide-lesson-7.htmlExposição na instrução PE
Materialmaterials/lesson-7-material.htmlAutoestudo
View engineejsTemplating server-side no Express
Body parserexpress.urlencodedForms tradicionais (application/x-www-form-urlencoded)
InspeçãoDevTools (Elements / Network)Inspecionar HTML renderizado e payload do form
Repositóriosrc/views/, src/views/partials/Templates EJS e parciais

Verificação de aprendizagem

  • CR-1EJS configurado e primeira página renderizada via res.render.
  • CR-2Pelo menos 1 partial reaproveitado em ≥ 2 páginas (include).
  • CR-3Desafio individual entregue: branch aula-7-tela-projeto com uma tela do wireframe replicada via res.render, layout + partials e HTML semântico (até 14h40).
  • CR-4Form tradicional persistindo dados (POST → controller → service → repository) com redirect.
  • CR-5Pelo menos 1 interação DOM (querySelector + addEventListener + classList).
  • CR-6Merge Request feat(views): telas X e Y aberto até as 16h00.
Critério mínimo

Aluno que sair às 16h sem ao menos a tela individual do wireframe entregue + integração no projeto + 1 form persistindo está em débito técnico para acompanhar a aula 8 (JS assíncrono e fetch).

Conexão com a aula 8

A aula 8 traz JavaScript assíncrono e fetch() para o cliente. O mesmo back-end que renderiza HTML passará a expor JSON paralelo, e a UI ganha interatividade dinâmica sem recarregar a página.

  • O controller ganha um par res.json(...) ao lado do res.render(...) — mesmos services, dois clientes (HTML SSR + JSON via fetch).
  • As validações zod da aula 6 continuam protegendo o servidor — mesmo com chamadas via fetch, a validação de domínio é a mesma.
Para o autoestudo da aula 8

Antes das 8h do próximo dia: ler o material da aula 8, listar 2 interações do projeto que ficariam melhores sem reload (ex.: filtro, autocomplete, like), e revisar Promises e async/await.

Inteli Logo