<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Layssa Lima</title>
    <description>The latest articles on Forem by Layssa Lima (@layssadev).</description>
    <link>https://forem.com/layssadev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F884196%2Fc32960f5-0cc7-48d9-8b0c-95a8fd44c1e9.jpeg</url>
      <title>Forem: Layssa Lima</title>
      <link>https://forem.com/layssadev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/layssadev"/>
    <language>en</language>
    <item>
      <title>Enfim, Domain Driven Design (DDD)</title>
      <dc:creator>Layssa Lima</dc:creator>
      <pubDate>Thu, 29 Jan 2026 22:24:24 +0000</pubDate>
      <link>https://forem.com/layssadev/enfim-ddd-padroes-de-projeto-no-front-end-parte-2-3bbf</link>
      <guid>https://forem.com/layssadev/enfim-ddd-padroes-de-projeto-no-front-end-parte-2-3bbf</guid>
      <description>&lt;h3&gt;
  
  
  Padrões de projeto no front-end. Parte 2.
&lt;/h3&gt;

&lt;p&gt;Esta é a parte 2 de uma sequência de artigos sobre desenvolvimento de software.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;O que é o DDD?&lt;/strong&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“É um conjunto de princípios com foco em domínio, exploração de modelos de formas criativas e definir e falar a linguagem Ubíqua, baseado no contexto delimitado."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Como falado no post anterior &lt;a href="https://dev.to/layssadev/padroes-de-projeto-no-front-end-1pip"&gt;(Padrões de projeto no front-end? - Parte 1)&lt;/a&gt;, projetos modulares conseguem oferecer um bom meio termo quando monolitos tornam-se caóticos e microsserviços confusos e necessitam de mais pessoas.&lt;/p&gt;

&lt;p&gt;Mas depois de entender que modularizar é um bom caminho para o projeto, entra o próximo desafio: &lt;strong&gt;definir os módulos.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;E essa parte é confusa, pois muitos módulos convergem uns nos outros.&lt;/p&gt;

&lt;p&gt;É nesse ponto que o DDD ajuda.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;DDD&lt;/strong&gt; possibilita a melhor modelagem do software, com foco nas regras da aplicação (princípos, regras e processos) que são complexas e precisam de atenção. Isso permite que o software evolua gradualmente e que diferentes áreas possam conversar entre si sem impactar a outra.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Quando usar?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Utiliza-lo só faz sentido em softwares complexos e apenas. &lt;br&gt;
Uma vez que a proposta é exatamente lidar com a complexidade com mais eficiência.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;O que faz um software ser complexo?&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;As regras de negócio.&lt;/li&gt;
&lt;li&gt;As àreas envolvidas e/ou relacionadas.&lt;/li&gt;
&lt;li&gt;A interpretação que cada pessoa tem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A transcrição dessas regras e interpretações em código é o que torna o software complexo.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;O DDD&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Domínios&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O DDD interpreta o projeto dividindo em duas classes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Domínio&lt;/li&gt;
&lt;li&gt;Subdomínio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O &lt;strong&gt;Domínio&lt;/strong&gt;: é o core do negócio.&lt;br&gt;
Exemplo: Um site para transmissões ao vivo.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;Subdomínio&lt;/strong&gt;: são as partes menores que compõe o domínio central.&lt;br&gt;
Exemplo: chats, players, canais e etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linguagem universal&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ele também ajuda a criar uma linguagem universal, padronizando a nomenclatura e facilitando a interpretação e conversação das àreas.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Bounded Contexts&lt;/strong&gt; ou &lt;strong&gt;Contexto delimitados&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;O Bounded Contexts consiste em separar a sua aplicação, onde cada sessão será um conjunto de termos, regras e definições consistentes.&lt;/p&gt;

&lt;p&gt;Enquanto escrevia esse artigo, eu vi um exemplo no reddit muito bom.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The 'bounded context' is a doll house, inside of it is where you keep things that 'belong' inside - a dining table, a kitchen, and a bathtub. You wouldn't put a tree or a road sign inside, because they don't belong inside.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Um outro exemplo muito bom da mesma thread é de um e-commerce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No site: &lt;strong&gt;O PEDIDO&lt;/strong&gt; tem informações importantes como preço, impostos e etc.&lt;/li&gt;
&lt;li&gt;No armazém: &lt;strong&gt;O PEDIDO&lt;/strong&gt; tem outra 'cara', nele o que mais importa são os códigos e endereços.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mesmo objeto. Valores e relevâncias diferentes.&lt;/p&gt;

&lt;p&gt;Assim, o pedido deve ter as informações necessárias em ambos os setores, mas cada uma é independente. &lt;br&gt;
O setor de pedidos pode adicionar outras formas de pagamentos ou o setor do armazém pode adicionar novas formas de entrega, as alterações não irão sobreescrever o que é relevante pra outra àrea.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.reddit.com/r/microservices/comments/1bms6dh/explain_me_like_im_5_what_the_bounded_context/" rel="noopener noreferrer"&gt;Veja a thread&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isso auxília na criação do design da aplicação, tornando-o mais estratégico.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design do sistema&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Com essa visão macro do sistema, é mais fácil mapear as entidades, os procedimentos e eventos de domínio envolvidas na aplicação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complexidade de negócio vs Complexidade Técnica&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Outra ponto que também é facilitado é separar a complexidade em dois contextos: o que é complexo devido as regras de negócio e o que é complexo por questões técnicas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problemas
&lt;/h2&gt;

&lt;p&gt;A visão macro construida até então do domínio, será o ponto de partida para enxergar os problemas que o sistema possui e assim criar subdomínios&lt;/p&gt;

&lt;p&gt;Para cada um dos subdomínios deve ser criado um Bounded Context(ver sessão anterior) para a solução final.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contexto é a chave primária pra nomenclatura
&lt;/h2&gt;

&lt;p&gt;Existe a possibilidade de uma mesma palavra ter significados diferentes, da mesma maneira, pode ocorrer de palavras diferentes, terem significados iguais. Logo, o ideial é delimitar o domínio para que essas entidade(s) possam co-existir. &lt;/p&gt;

&lt;h3&gt;
  
  
  Diferentes entidades, mesmo nome
&lt;/h3&gt;

&lt;p&gt;Imagine uma empresa b2b e b2c, &lt;strong&gt;customer&lt;/strong&gt; para o b2b é uma empresa, com informações e funções diferentes, enquanto que para o b2c é algo totalmente diferente. Ambos são salvos na entidade 'customer'. Para total compreensão e controle das features, o ideal seria delimitar essas entidades em contextos diferentes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mesma entidade, funcionalidades diferentes
&lt;/h3&gt;

&lt;p&gt;Voltando ao exemplo do pedido, o pedido é um só para o site e para o armazé, porém, necessitam de features diferentes.&lt;/p&gt;

&lt;p&gt;No site, a entidade pedido precisa lidar com compra/venda&lt;br&gt;
No armazém, retirada, transporte e entrega.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Padrões de mapeamento de contexto&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Partnership&lt;/li&gt;
&lt;li&gt;Shared Kernel&lt;/li&gt;
&lt;li&gt;Customer-Supplier Development&lt;/li&gt;
&lt;li&gt;Conformist &lt;/li&gt;
&lt;li&gt;Anticorruption-layer&lt;/li&gt;
&lt;li&gt;Open host service&lt;/li&gt;
&lt;li&gt;Published language&lt;/li&gt;
&lt;li&gt;Separate ways&lt;/li&gt;
&lt;li&gt;Big Ball of Mud&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Mapeamento de contextos
&lt;/h2&gt;

&lt;p&gt;Considerando o exemplo inicial, um site para transmissões ao vivo.&lt;/p&gt;

&lt;p&gt;Back-end&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftj6bytc33srkc8n433j7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftj6bytc33srkc8n433j7.png" alt=" " width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Front-end&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftkil5f8au95aifwx09tw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftkil5f8au95aifwx09tw.png" alt=" " width="686" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ddd</category>
      <category>programming</category>
      <category>project</category>
    </item>
    <item>
      <title>Padrões de projeto no front-end? - Parte 1</title>
      <dc:creator>Layssa Lima</dc:creator>
      <pubDate>Thu, 20 Nov 2025 18:19:43 +0000</pubDate>
      <link>https://forem.com/layssadev/padroes-de-projeto-no-front-end-1pip</link>
      <guid>https://forem.com/layssadev/padroes-de-projeto-no-front-end-1pip</guid>
      <description>&lt;p&gt;Alguns meses atrás me deparei com a necessidade de refazer um projeto front-end do zero. Isso me levou a uma busca por padrões de projetos aplicados ao front-end - algo que, particularmente, não é tão fácil de encontrar quanto no back-end.&lt;/p&gt;

&lt;p&gt;Depois de algum tempo estudando sobre monolitos, micro front-ends e monolitos modulares, cheguei a algumas reflexões que rascunho abaixo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Micro front-end vs. Monolito Modular vs. Monolito
&lt;/h3&gt;

&lt;p&gt;Uma das primeiras questões que veio à mente foi: &lt;strong&gt;qual dos modelos adotar?&lt;/strong&gt; Para isso, considerei os pontos abaixo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Micro front-end&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwimh9kv10i4q8trmbuhq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwimh9kv10i4q8trmbuhq.png" alt=" " width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;br&gt;
Permite que módulos da aplicação sejam desenvolvidos e implantados de forma totalmente independente. Isso reduz acoplamento, facilita escalabilidade e permite que times diferentes evoluam partes distintas da aplicação no seu próprio ritmo. Também possibilita escalar recursos de forma isolada para apenas os serviços que precisam.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contras&lt;/strong&gt;&lt;br&gt;
Em contrapartida, aumenta a complexidade da arquitetura. Requer mais infraestrutura, mais pipelines, mais pessoas para dar suporte e, consequentemente, maior custo de cloud. Também exige maturidade para lidar com versionamento, comunicação entre módulos e consistência visual.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monolito&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnu4drhtyg0jhmaxezqt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnu4drhtyg0jhmaxezqt.png" alt=" " width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;br&gt;
É um modelo clássico, simples de gerenciar e que costuma atender bem a maioria das necessidades. O código fica centralizado, o deploy é único e os custos — tanto de pessoal, quanto de infraestrutura — tendem a ser menores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contras&lt;/strong&gt;&lt;br&gt;
Com o tempo, pode se tornar uma base de código altamente acoplada e difícil de manter. À medida que a equipe cresce, o fluxo de trabalho paralelo tende a gerar conflitos e gargalos. Escalar o sistema geralmente exige aumentar recursos da máquina inteira, e não apenas da parte que realmente precisa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monolito Modular&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyz16bngaymw271p771d2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyz16bngaymw271p771d2.png" alt=" " width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O monolito modular traz um ponto de equilíbrio entre os dois extremos. Ele mantém um único projeto e um único deploy, mas organiza o código em módulos bem separados, com responsabilidades claras, limites explícitos e baixo acoplamento.&lt;/p&gt;

&lt;p&gt;Dessa forma, múltiplas pessoas podem trabalhar em paralelo — desde que estejam em módulos distintos — sem o mesmo nível de conflito de um monolito comum. Além disso, caso algum módulo precise virar um serviço independente no futuro, o esforço de extração tende a ser muito menor do que em um monolito tradicional.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mas existe um ponto crucial para que esses módulos façam sentido: DDD. E esse é um tema que vale um artigo próprio.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>frontend</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Construindo uma Aplicação com Comunicação em Tempo Real Usando Fastify, RabbitMQ e Arquitetura Distribuída</title>
      <dc:creator>Layssa Lima</dc:creator>
      <pubDate>Thu, 07 Aug 2025 22:33:38 +0000</pubDate>
      <link>https://forem.com/layssadev/construindo-uma-aplicacao-com-comunicacao-em-tempo-real-usando-fastify-rabbitmq-e-arquitetura-29gi</link>
      <guid>https://forem.com/layssadev/construindo-uma-aplicacao-com-comunicacao-em-tempo-real-usando-fastify-rabbitmq-e-arquitetura-29gi</guid>
      <description>&lt;p&gt;Há cerca de três meses, participei de um desafio que me deixou bastante empolgada.&lt;br&gt;
Por essa razão resolvi compartilhar como foi o processo de desenvolvimento, as escolhas técnicas que fiz e alguns aprendizados ao longo do caminho.&lt;/p&gt;

&lt;p&gt;Aceito sugestões de melhorias.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Spoiler: o projeto está apenas no começo, ainda há muito para ser desenvolvido, inicialmente estou compartilhando apenas o que foi feito em um desafio entre 3 e 4 dias&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Repositório: &lt;a href="https://github.com/Layssaa/dwitch" rel="noopener noreferrer"&gt;Dwitch&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;O DESAFIO&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O objetivo era criar uma aplicação completa:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frontend e backend&lt;/li&gt;
&lt;li&gt;Autenticação&lt;/li&gt;
&lt;li&gt;Persistência de dados&lt;/li&gt;
&lt;li&gt;Observabilidade&lt;/li&gt;
&lt;li&gt;Mensageria&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tudo isso em uma arquitetura distribuída, com documentação do projeto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ponto de partida
&lt;/h3&gt;

&lt;p&gt;O primeiro passo foi decidir qual aplicação desenvolver. Como eu já tinha interesse em me aprofundar no tema, optei por criar uma aplicação de transmissão ao vivo, mesmo sabendo que o tempo disponível não permitiria implementar todas as funcionalidades reais desse tipo de sistema.&lt;/p&gt;

&lt;h3&gt;
  
  
  Arquitetura
&lt;/h3&gt;

&lt;p&gt;O passo seguinte foi definir a arquitetura.&lt;br&gt;
Comecei pensando nas funcionalidades que o sistema deveria ter, organizando-as em módulos e alinhando tudo aos requisitos do desafio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfp2uip6grg4lh6o0j85.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfp2uip6grg4lh6o0j85.png" alt="Diagrama da arquitetura do projeto" width="708" height="558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No desenho, temos um banco PostgreSQL centralizando os dados do sistema e quatro módulos principais:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auth&lt;/strong&gt; - autenticação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Channels&lt;/strong&gt; - CRUD de canais.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User&lt;/strong&gt; - CRUD de usuários.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Broadcast&lt;/strong&gt; - comunicação das transmissões.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Nesse estágio inicial, optei por simular a comunicação em tempo real por meio de mensagens — algo que é bem diferente de uma transmissão ao vivo real, mas que atendia ao escopo e tempo do desafio.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Sobre os módulos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Os módulos foram implementados com Fastify, cuja sintaxe é bastante familiar para quem já trabalhou com Express.&lt;br&gt;
Para mensageria, utilizei RabbitMQ.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modelagem dos dados
&lt;/h3&gt;

&lt;p&gt;Após visualizar a aplicação e a arquitetura, passei para a modelagem do banco de dados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5ep1aqkqtm3kvb59rpk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5ep1aqkqtm3kvb59rpk.png" alt="Modelagem das tabelas do banco da aplicação" width="629" height="711"&gt;&lt;/a&gt;&lt;br&gt;
Nessa modelagem, estabeleci:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A relação entre usuários e canais&lt;/li&gt;
&lt;li&gt;A relação entre canais e transmissões&lt;/li&gt;
&lt;li&gt;O vínculo das transmissões com seus respectivos logs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dessa forma, é possível acompanhar o status de cada transmissão e manter um histórico de alterações.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ferramentas utilizadas nessa etapa
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Diagramas: Draw.io&lt;/li&gt;
&lt;li&gt;APIs: Fastify&lt;/li&gt;
&lt;li&gt;Mensageria: RabbitMQ&lt;/li&gt;
&lt;li&gt;Protocolos: HTTP e WebSocket&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 Próximos passos: no próximo post, quero detalhar como implementei cada módulo e como configurei a comunicação entre eles.&lt;/p&gt;

&lt;p&gt;Se tiverem dúvidas ou sugestões de melhorias, deixem nos comentários!&lt;/p&gt;

</description>
      <category>fastify</category>
      <category>architecture</category>
      <category>software</category>
      <category>eventdriven</category>
    </item>
    <item>
      <title>Building an Application with Real-Time Communication Using Fastify, RabbitMQ, and a Distributed Architecture</title>
      <dc:creator>Layssa Lima</dc:creator>
      <pubDate>Thu, 07 Aug 2025 21:32:14 +0000</pubDate>
      <link>https://forem.com/layssadev/building-a-real-time-application-with-fastify-rabbitmq-and-a-distributed-architecture-1h4h</link>
      <guid>https://forem.com/layssadev/building-a-real-time-application-with-fastify-rabbitmq-and-a-distributed-architecture-1h4h</guid>
      <description>&lt;p&gt;About three months ago, I took part in a challenge that got me really excited.&lt;br&gt;
That’s why I decided to share how the development process went, the technical choices I made, and some lessons I learned along the way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Github&lt;/strong&gt;: &lt;a href="https://github.com/Layssaa/dwitch" rel="noopener noreferrer"&gt;Dwitch&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m open to suggestions for improvement.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Spoiler: the project is just getting started — there's still a lot to be developed.&lt;br&gt;
What I'm sharing here is only what was built during a 3-to-4-day challenge.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  THE CHALLENGE
&lt;/h3&gt;

&lt;p&gt;The goal was to create a complete application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frontend and backend&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Data persistence&lt;/li&gt;
&lt;li&gt;Observability&lt;/li&gt;
&lt;li&gt;Messaging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this in a distributed architecture, with proper project documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Starting point
&lt;/h3&gt;

&lt;p&gt;The first step was to decide what kind of application to build.&lt;br&gt;
Since I already had an interest in exploring the topic, I chose to create a live streaming application — even knowing that the available time wouldn’t allow me to implement all the real-world features of such a system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;The next step was to define the architecture.&lt;br&gt;
I started by thinking about the functionalities the system should have, organizing them into modules, and aligning everything with the challenge’s requirements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc6nru2qyr85ybtzmjb7v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc6nru2qyr85ybtzmjb7v.png" alt="Architecture" width="708" height="558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the diagram, we have a PostgreSQL database centralizing the system’s data and four main modules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auth&lt;/strong&gt; – authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Channels&lt;/strong&gt; – channel CRUD&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User&lt;/strong&gt; – user CRUD&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Broadcast&lt;/strong&gt; – stream communication&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;At this initial stage, I chose to simulate real-time communication using messaging — which is quite different from actual live streaming — but it fit the scope and time constraints of the challenge.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  About the modules
&lt;/h3&gt;

&lt;p&gt;The modules were implemented with Fastify, whose syntax is very familiar to anyone who has worked with Express.&lt;br&gt;
For messaging, I used RabbitMQ.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data modeling
&lt;/h3&gt;

&lt;p&gt;After visualizing the application and its architecture, I moved on to database modeling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6mb5htn6mbk3ky4z0jz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6mb5htn6mbk3ky4z0jz.png" alt="data model" width="629" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this model, I defined:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The relationship between users and channels&lt;/li&gt;
&lt;li&gt;The relationship between channels and streams&lt;/li&gt;
&lt;li&gt;The link between streams and their respective logs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This structure makes it possible to track the status of each stream and keep a history of changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tools used in this stage
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Diagrams: Draw.io&lt;/li&gt;
&lt;li&gt;APIs: Fastify&lt;/li&gt;
&lt;li&gt;Messaging: RabbitMQ&lt;/li&gt;
&lt;li&gt;Protocols: HTTP and WebSocket&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 Next steps: In the next post, I’ll detail how I implemented each module and how I set up communication between them.&lt;/p&gt;

&lt;p&gt;If you have any questions or suggestions for improvement, feel free to leave them in the comments!&lt;/p&gt;

</description>
      <category>fastify</category>
      <category>architecture</category>
      <category>eventdriven</category>
      <category>software</category>
    </item>
    <item>
      <title>Docker: O Que Aprendi na Semana 1 de estudo</title>
      <dc:creator>Layssa Lima</dc:creator>
      <pubDate>Thu, 13 Mar 2025 02:16:50 +0000</pubDate>
      <link>https://forem.com/layssadev/docker-o-que-aprendi-na-semana-1-de-estudo-136m</link>
      <guid>https://forem.com/layssadev/docker-o-que-aprendi-na-semana-1-de-estudo-136m</guid>
      <description>&lt;p&gt;Nos últimos 6 meses, decidi que focaria na minha carreira e começaria a estudar novas ferramentas. Uma dessas ferramentas é o docker, nesse artigo vou compartilhar importantes conceitos que aprendi na minha primeira semana.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Containers&lt;/li&gt;
&lt;li&gt;Containers vs Máquina virtual&lt;/li&gt;
&lt;li&gt;Primeiros passos com docker&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Containers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Um container é um ambiente isolado para empacotar aplicações, isolando processos e recursos. &lt;/li&gt;
&lt;li&gt;A maneira como são montados permite que não consumam muitos recursos da máquina, pois são executados como um processo do sistema operacional da máquina host.&lt;/li&gt;
&lt;li&gt;Devido a essas características, cada um pode ser iniciado e parado rapidamente.&lt;/li&gt;
&lt;li&gt;São construídos utilizando imagens — que são imutáveis.&lt;/li&gt;
&lt;li&gt;A proposta do docker é equalizar ambientes e evitar problemas dessa natureza.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Containers vs Máquina virtual
&lt;/h3&gt;

&lt;p&gt;Antes dos containers era comum utilizar máquinas virtuais.&lt;br&gt;
Mas qual é a diferença?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Máquinas virtuais&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bem, pra começar as máquinas virtuais possuem um sistema operacional individual, ou seja, pra cada máquina virtual, temos um novo sistema operacional completo, incluindo kernel. Além disso, possui um hypervisor para gerenciar as máquinas.&lt;/p&gt;

&lt;p&gt;Isso faz com que seja necessário mais recursos, que são usados com menos eficiência, e mais tempo de inicialização.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Containers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Por outro lado, containers compartilham o kernel com o host e mantém a aplicação e dependências isoladas.&lt;/p&gt;

&lt;p&gt;Consequentemente, os containers possuem mais eficiência no uso de recursos e têm inicialização mais rápida.&lt;/p&gt;

&lt;p&gt;Isso faz com que os containers sejam mais apropriados para escalabilidade e permite a execução de muitas aplicações no host.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2bh14amlq8ku0do4i7j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2bh14amlq8ku0do4i7j.png" alt=" " width="768" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O ponto de falha do docker é que todos os containers são controlados pelo docker daemon, uma vez que ele caia, todos os outros caem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Primeiros passos com docker
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Instalando o docker&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para instalar na sua máquina, siga os passos do tutorial do seu sistema operacional:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/desktop/setup/install/windows-install/" rel="noopener noreferrer"&gt;Windows&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.docker.com/desktop/setup/install/linux/" rel="noopener noreferrer"&gt;Linux&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.docker.com/desktop/setup/install/mac-install/" rel="noopener noreferrer"&gt;Mac&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Primeiros comandos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inicia container com a imagem informada e gera nome randômico.&lt;br&gt;
&lt;code&gt;docker run &amp;lt;nome da imagem&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Inicia container com a imagem informada e com o nome 'teste'.&lt;br&gt;
&lt;code&gt;docker run --name=teste &amp;lt;nome da imagem&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Remove container com o ID informado - se estiver parado&lt;br&gt;
&lt;code&gt;docker rm &amp;lt;container_ID&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Remove container com o nome informado - se estiver parado&lt;br&gt;
&lt;code&gt;docker rm &amp;lt;container_name&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Força remoção do container -  mesmo que esteja parado.&lt;br&gt;
&lt;code&gt;docker rm -f &amp;lt;container_name&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attach e Detach&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ao iniciar um container seu terminal ficará travado, para evitar isso, faça o &lt;strong&gt;detach&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -d &amp;lt;container_id | container_name | image&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Mas caso deseje ler os logs do container no terminal, faça:&lt;br&gt;
&lt;code&gt;docker attach &amp;lt;container_id&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remoção automática do container após paralização&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para isso, faça:&lt;br&gt;
&lt;code&gt;docker run --rm &amp;lt;image&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Portas dos containers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A porta usada no container é exposta internamente, de maneira que acessando a partir da sua máquina, não é possível acessa-la.&lt;/p&gt;

&lt;p&gt;No entanto, para fazer essa configuração, faça:&lt;br&gt;
&lt;code&gt;docker run -p 8080:80&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A porta 8080 da sua máquina irá refletir a porta 80 do container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Persistência de dados e volumes: Bind mounts vs volumes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ao parar um container, os dados dentro dele serão perdidos, mas uma forma de contornar isso é utilizando Bind mounts ou volumes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Bind mounts&lt;br&gt;
Compartilha pasta com o host, caso a pasta seja modificada localmente, será refletida no container, é útil em ambientes de desenvolvimento.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volumes&lt;br&gt;
São gerenciados por pastas isoladas, salvas nos arquivos do host, e são mais performáticos, ideais para produção.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Comandos Bind mounts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Criando Bind Mount:&lt;br&gt;
&lt;code&gt;docker run -dp 3333:80 -v caminho_pasta_local:caminho_pasta_container &amp;lt;imagem&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comandos Bind mounts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Criando volume:&lt;br&gt;
&lt;code&gt;docker volume create &amp;lt;volume_nome&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backups com busybox&lt;/strong&gt;&lt;br&gt;
É uma imagem de utilitários linux, pode ser útil para fazer backups.&lt;/p&gt;

&lt;p&gt;Compactar e fazer backup.&lt;br&gt;
&lt;code&gt;docker run --rm -it -v volume_nome:/data -v $(pwd)/backup_host:/backup busybox tar czf /backup/backup.tar.gz /data&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Descompactar e restaurar backup.&lt;br&gt;
&lt;code&gt;docker run --rm -it -v volume_nome:/data -v $(pwd)/backup_host:/backup busybox tar xzf /backup/backup.tar.gz -C /data&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;Esses foram os conceitos que aprendi na minha primeira semana explorando Docker. Em breve, trarei mais descobertas e práticas!&lt;/p&gt;

</description>
      <category>docker</category>
    </item>
    <item>
      <title>How set Google Tag Manager (GTM) on Nextjs applications with differents themes and IDs</title>
      <dc:creator>Layssa Lima</dc:creator>
      <pubDate>Fri, 14 Feb 2025 17:54:11 +0000</pubDate>
      <link>https://forem.com/layssadev/how-set-google-tag-manager-gtm-on-nextjs-applications-with-differents-themes-and-ids-3jk2</link>
      <guid>https://forem.com/layssadev/how-set-google-tag-manager-gtm-on-nextjs-applications-with-differents-themes-and-ids-3jk2</guid>
      <description>&lt;p&gt;This week, I needed to solve a problem with Google Tag Manager (GTM).&lt;/p&gt;

&lt;p&gt;The problem was that my platform has different themes for each client, and I needed to insert the GTM code for each theme.&lt;/p&gt;

&lt;h3&gt;
  
  
  The problem:
&lt;/h3&gt;

&lt;p&gt;Google Tag Manager (GTM) was not working correctly because its ID was being dynamically loaded on the client side. However, GTM needs to be available immediately when the page loads. This caused issues such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;GTM not initializing at the right time.&lt;/li&gt;
&lt;li&gt;Important tracking events (like pageviews) being lost.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// This will not work
function Example(gtmId){
 return &amp;lt;GoogleTagManager gtmId={gtmId} /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Solutions Attempted
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Loading GTM as a Dynamic Component:&lt;/strong&gt;
GTM was loaded as a dynamic component after the page rendered, which delayed execution and prevented it from working correctly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loading GTM Dynamically on the Client Side:&lt;/strong&gt;
GTM was also loaded only on the client side, but since it needs to be available at the initial page load, this approach failed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The solution
&lt;/h3&gt;

&lt;p&gt;To ensure GTM loads during the initial page render, we use the following approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define Preconfigured GTM Instances
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const GoogleTagManagerInstancies: { [key: string]: () =&amp;gt; JSX.Element } = {
  cobrand1: () =&amp;gt; &amp;lt;GoogleTagManager gtmId="GTM-XXXXXX" /&amp;gt;,
  cobrand2: () =&amp;gt; &amp;lt;GoogleTagManager gtmId="GTM-YYYYYY" /&amp;gt;,
  default: () =&amp;gt; &amp;lt;&amp;gt;&amp;lt;/&amp;gt;,
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Select GTM Based on Theme
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const WaGoogleTagManager = GoogleTagManagerInstancies[activeTheme ?? "default"];

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Render the Component
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;WaGoogleTagManager /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Does This Work?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;GTM is statically defined at the initial page load.&lt;/li&gt;
&lt;li&gt;The GTM ID is resolved before rendering, ensuring the script loads at the right time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The issue was caused by GTM being loaded too late, preventing it from executing correctly. The solution ensures that GTM is loaded before rendering, using preconfigured instances and direct rendering in the HTML.&lt;/p&gt;

</description>
      <category>googletagmanager</category>
      <category>webdev</category>
      <category>nextjs</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Tudo o que você precisa saber sobre Next.JS para iniciar um novo projeto hoje</title>
      <dc:creator>Layssa Lima</dc:creator>
      <pubDate>Wed, 18 Dec 2024 22:12:24 +0000</pubDate>
      <link>https://forem.com/layssadev/tudo-o-que-voce-precisa-saber-sobre-nextjs-para-iniciar-um-novo-projeto-hoje-2cg2</link>
      <guid>https://forem.com/layssadev/tudo-o-que-voce-precisa-saber-sobre-nextjs-para-iniciar-um-novo-projeto-hoje-2cg2</guid>
      <description>&lt;ol&gt;
&lt;li&gt;Introdução&lt;/li&gt;
&lt;li&gt;O Projeto&lt;/li&gt;
&lt;li&gt;Iniciando&lt;/li&gt;
&lt;li&gt;Criando rotas&lt;/li&gt;
&lt;li&gt;Organizando as rotas da plataforma&lt;/li&gt;
&lt;li&gt;Controlando as Rotas do Projeto&lt;/li&gt;
&lt;li&gt;Conclusão&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Tudo o que você precisa saber sobre Next.JS para iniciar um novo projeto hoje&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1 Introdução
&lt;/h2&gt;

&lt;p&gt;Next.js é um poderoso framework React que vai além do desenvolvimento apenas de front-end. Enquanto o React normalmente se concentra em construir interfaces de usuário, o Next.js possibilita a criação de aplicações full-stack, lidando tanto com o front-end quanto com o back-end em um único framework unificado. Essa abordagem é frequentemente chamada de "Backend for Frontend" (BFF), permitindo criar aplicações completas e robustas com facilidade.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Links importantes:&lt;br&gt;
&lt;a href="https://github.com/Layssaa/learning-nextjs" rel="noopener noreferrer"&gt;Repositório no Github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2 O Projeto
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;O objetivo deste projeto é criar um site de eventos voltado para a venda de ingressos. A plataforma oferecerá ingressos para diversos tipos de eventos e contará com quatro páginas principais: a página de login, um feed de eventos, o processo de compra e a página de resumo do pedido. Abaixo, você encontrará imagens de pré-visualização de cada layout de página.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  3 Iniciando
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Instale &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;o Node.JS 18.8 ou superior.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Criando o projeto:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em seguida, o terminal exibirá algumas perguntas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Este será o nome do seu projeto
What is your project named? eve

// **YES** - Usar typescript melhora a compreensão do código
Would you like to use TypeScript? No / Yes

// **YES** - Eslint ajuda a evitar erros 
Would you like to use ESLint? No / Yes

// **NO** - Neste projeto será usado styled-components
Would you like to use Tailwind CSS? No / Yes

// **YES**
Would you like your code inside a `src/` directory? No / Yes

// **YES**
Would you like to use App Router? (recommended) No / Yes

// **NO**
Would you like to use Turbopack for `next dev`?  No / Yes

// **NO**
Would you like to customize the import alias (`@/*` by default)? No / Yes
What import alias would you like configured? @/*

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Agora você pode rodar o comando abaixo para ver a página padrão do Next.js:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternativamente, você pode usar este comando para construir a aplicação como páginas estáticas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  npm run start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4 Criando rotas
&lt;/h2&gt;

&lt;p&gt;O Next.js fornece uma maneira fácil de lidar com rotas na aplicação com base nos nomes dos caminhos. Vamos explorar cada caso.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Rotas comuns
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No diretório /src/app, procure o arquivo page.tsx. Esse será o arquivo exibido por padrão ao acessar &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Agora, crie uma nova rota: no diretório src/app, crie uma pasta chamada auth. Dentro dela, crie o arquivo page.tsx e adicione o seguinte código:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function Auth() {
  return &amp;lt;div&amp;gt;login&amp;lt;/div&amp;gt;;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao acessar &lt;a href="http://localhost:3000/auth" rel="noopener noreferrer"&gt;http://localhost:3000/auth&lt;/a&gt;, você verá o texto "login".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07ht41j14vhiyy3q4q5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07ht41j14vhiyy3q4q5z.png" alt=" " width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2 - &lt;a href="https://nextjs.org/docs/app/building-your-application/routing/route-groups" rel="noopener noreferrer"&gt;Agrupamento de rotas&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Para organizar o código sem impactar a estrutura das URLs, renomeie a pasta auth para (auth) e crie um subdiretório login, mova o arquivo page.tsx para ela.&lt;/p&gt;

&lt;p&gt;Agora, verifique duas coisas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a URL /auth exibirá um erro 404.&lt;/li&gt;
&lt;li&gt;a URL /login exibirá o componente corretamente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essa abordagem organiza o projeto em módulos sem afetar a experiência do usuário.&lt;/p&gt;

&lt;h4&gt;
  
  
  4 - &lt;a href="https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes" rel="noopener noreferrer"&gt;Rotas dinâmicas&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Crie uma rota dinâmica, ideal para páginas que precisam exibir conteúdo variável, como detalhes de um evento.&lt;/p&gt;

&lt;p&gt;No diretório /app, crie uma pasta events e, dentro dela, outra chamada [id]. O nome com colchetes indica uma rota dinâmica.&lt;/p&gt;

&lt;p&gt;No arquivo page.tsx dentro da pasta [id], adicione:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// O comando 'use client' é uma diretiva usada no Next.js para indicar que um arquivo ou componente deve ser executado no lado do cliente.
'use client' 

import { useParams } from "next/navigation";

export default function EventInfo() {
    const params = useParams(); // Retrieve URL parameters

    return &amp;lt;div&amp;gt;{params.id}&amp;lt;/div&amp;gt;;
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Acesse &lt;a href="http://localhost:3000/events/111" rel="noopener noreferrer"&gt;http://localhost:3000/events/111&lt;/a&gt; para visualizar a página.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9josvihirw9a7rgukpi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9josvihirw9a7rgukpi.png" alt=" " width="543" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5 Organizando as rotas da plataforma
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Instalando dependências:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i styled-components react-query 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Criando rotas de autenticação e plataforma
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Autenticação: Crie um diretório (auth) com subdiretórios login e register. &lt;/li&gt;
&lt;li&gt;Plataforma: No diretório app, crie uma pasta platform com subdiretórios [id] e purchase.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahebqk6c8mhgjy671fsv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahebqk6c8mhgjy671fsv.png" alt=" " width="291" height="101"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rotas privadas da plataforma&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dentro da pasta &lt;code&gt;app&lt;/code&gt; crie uma pasta chamada 'platform', em seguida crie as seguintes sub pastas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[id]&lt;/li&gt;
&lt;li&gt;purchase&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A estrutura das pastas deve parecer com isso:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcff3855iwfrfi21tgq5n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcff3855iwfrfi21tgq5n.png" alt=" " width="207" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nesse momento, iremos criar pastas genéricas, pois este arquivo foca no funcionamento do Next.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  6 Controlando as Rotas do Projeto - &lt;a href="https://nextjs.org/docs/app/building-your-application/routing/middleware" rel="noopener noreferrer"&gt;Middlewares&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;No nosso projeto haverá rotas públicas e privadas, para controlar esse acesso utilizaremos o &lt;strong&gt;middleware&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  O que é um Middleware?
&lt;/h3&gt;

&lt;p&gt;Middleware é uma função executada a cada solicitação de página. Isso permite gerenciar as rotas, autenticação e outras regras. Para isso:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Crie um arquivo chamado middleware.ts na pasta &lt;code&gt;src&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Adicione o seguinte código:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export default function middleware(request: NextRequest) {
  return NextResponse.redirect(new URL('/home', request.url))
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Adicionando regras às rotas.
&lt;/h3&gt;

&lt;p&gt;No mesmo arquivo, adicione dois arrays para categorizar dois tipos de rotas - públicas e privadas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Rotas privadas - necessita de autenticação
const protectedRoutes = ["/platform"];

// Rotas públicas - não necessita de autenticação
const publicRoutes = ["/login", "/register"];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verificando as regras da rota e a sessão do usuário&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Atualize a função do middleware para incluir as validações das rotas e checar a sessão:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl; // URL being accessed
  const userId = request.cookies.get("user-id"); // User session check

  // Função que  verifica se a rota é privada
  const isPrivateRouter = protectedRoutes.some((path: string) =&amp;gt;
    pathname.startsWith(path)
  );

  if (isPrivateRouter &amp;amp;&amp;amp; userId) {
    return NextResponse.next();
  }

  if (isPrivateRouter &amp;amp;&amp;amp; !userId) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  // Função que  verifica se a rota é pública
  const isPublicRouter = publicRoutes.some((path: string) =&amp;gt;
    pathname.startsWith(path)
  );

  if (isPublicRouter &amp;amp;&amp;amp; !userId) {
    return NextResponse.next();
  }

  if (isPublicRouter &amp;amp;&amp;amp; userId) {
    return NextResponse.redirect(new URL("/platform", request.url));
  }

  // Redireciona para o login se a rota for inválida
  return NextResponse.redirect(new URL("/login", request.url));
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Pular execução do middleware em rotas específicas
&lt;/h3&gt;

&lt;p&gt;Se você não quer que o middleware execute em algumas rotas, no mesmo arquivo deve adicionar o seguinte código no arquivo middleware.ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const config = {
  matcher: ['/login'], // não será executada na rota /login
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7 Navegando entre rotas
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Antes de seguir, desabilite o middleware.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffx3ex88vcwl5j1yx2b07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffx3ex88vcwl5j1yx2b07.png" alt=" " width="493" height="130"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Utilizando Next.js para navegar&lt;/p&gt;

&lt;p&gt;Next.js permite duas formas para navegação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Utilizando Link
&lt;/h3&gt;

&lt;p&gt;Para navegação por links, use o componente &lt;code&gt;Link&lt;/code&gt; do Next.js em vez da tag &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; padrão do HTML. Isso evita o recarregamento completo da página, proporcionando um melhor desempenho e uma experiência de usuário mais suave.&lt;/p&gt;

&lt;p&gt;Exemplo: Crie um botão na página de login para navegar até a plataforma.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnkast070ky96jbxlkljp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnkast070ky96jbxlkljp.png" alt=" " width="422" height="162"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao clicar no botão, a navegação causará o recarregamento da página.&lt;/p&gt;

&lt;p&gt;Então, vamos tentar usar o componente do Next.js.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6fdcg37qgmpg2u42zq48.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6fdcg37qgmpg2u42zq48.png" alt=" " width="479" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao clicar no botão, a navegação ocorrerá sem recarregar a página inteira.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usando o Hook do Router
&lt;/h3&gt;

&lt;p&gt;Como alternativa, você pode usar o hook router do Next.js para navegação programática.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd29gc7kr3aov73jkw6g6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd29gc7kr3aov73jkw6g6.png" alt=" " width="662" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essa abordagem também garante transições suaves e cria a sensação de uma aplicação de página única (SPA).&lt;/p&gt;

&lt;p&gt;Com esses métodos, você pode oferecer uma experiência de navegação fluida para os usuários.&lt;/p&gt;

&lt;h2&gt;
  
  
  7 Conclusão
&lt;/h2&gt;

&lt;p&gt;Neste artigo, exploramos os principais recursos do Next.js, incluindo os fundamentos de roteamento, criação de páginas dinâmicas e aninhadas, organização de código com grupos de rotas e implementação de autenticação e controle de acesso usando middleware. Além disso, aprendemos a otimizar a navegação para uma melhor experiência do usuário, aproveitando o componente Link e o roteamento programático com o hook useRouter. Esses conceitos estabelecem uma base sólida para a criação de aplicações escaláveis e amigáveis ao usuário com Next.js.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>web</category>
      <category>webdev</category>
      <category>website</category>
    </item>
    <item>
      <title>Integrating Storybook into an existing next.js project</title>
      <dc:creator>Layssa Lima</dc:creator>
      <pubDate>Wed, 18 Dec 2024 21:32:08 +0000</pubDate>
      <link>https://forem.com/layssadev/doing-integrating-storybook-into-an-existing-nextjs-project-34g8</link>
      <guid>https://forem.com/layssadev/doing-integrating-storybook-into-an-existing-nextjs-project-34g8</guid>
      <description>&lt;p&gt;In this article, you'll learn how to integrate Storybook into an existing Next.js project, including support for different themes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Storybook is an open-source tool that allows developers to build, test, and document UI components in isolation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install storybook&lt;/strong&gt;&lt;br&gt;
To get started, initialize Storybook in your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx storybook@latest init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configure Your Project&lt;/strong&gt;&lt;br&gt;
Below is an example configuration for integrating Storybook with a Next.js project:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;main.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// main.ts

import type { StorybookConfig } from '@storybook/nextjs'

import { join, dirname } from 'path'

function getAbsolutePath(value: string): any {
  return dirname(require.resolve(join(value, 'package.json')))
}

const config: StorybookConfig = {
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  addons: [
    getAbsolutePath('@storybook/addon-onboarding'),
    getAbsolutePath('@storybook/addon-essentials'),
    getAbsolutePath('@chromatic-com/storybook'),
    getAbsolutePath('@storybook/addon-interactions'),
  ],
  framework: {
    name: '@storybook/nextjs',
    options: {},
  },
  staticDirs: ['../public'],
}

export default config

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;preview.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// preview.ts

import { Preview } from '@storybook/react'
import { themesNames } from '../src/theme'

// Contexts providers
import { withThemeProvider } from './themeProvider'

import { RouterContext } from 'next/dist/shared/lib/router-context.shared-runtime'

export const globalTypes = {
  parameters: {
    nextRouter: {
      Provider: RouterContext.Provider,
    },
  },
  theme: {
    name: 'Theme',
    description: 'Global theme for components',
    defaultValue: 'defaultTheme',
    toolbar: {
      icon: 'paintbrush',
      items: themesNames,
      showName: true,
    },
  }
}

const preview: Preview = {
  decorators: [withThemeProvider],
}

export default preview

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; When configuring Storybook with custom providers, such as themes or global contexts, it’s essential to mock these contexts properly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context Providers Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;themeProvider.tsx&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// themeProvider.tsx

import React from 'react'
import { ThemeProvider } from 'styled-components'
import { Decorator } from '@storybook/react'
import { QueryClient, QueryClientProvider } from 'react-query'
import { AppRouterContext } from 'next/dist/shared/lib/app-router-context.shared-runtime'
import { GlobalStyle } from '../src/styles/Global.styles'

const queryClient = new QueryClient()

const themes = {
  // ... all project themes
  // 'projectName' : { ...settings}
}

// Contexts providers
export const withThemeProvider: Decorator = (Story, context) =&amp;gt; {
  const selectedTheme = context.globals.theme ?? 'defaultTheme'

  return (
    &amp;lt;QueryClientProvider client={queryClient}&amp;gt;
      &amp;lt;AppRouterContext.Provider
        // Overriding nextjs router functions
        value={{
          push: async () =&amp;gt; true,
          replace: async () =&amp;gt; true,
          back: () =&amp;gt; {},
          prefetch: async () =&amp;gt; {},
          forward: () =&amp;gt; {},
          refresh: () =&amp;gt; {},
        }}
      &amp;gt;
        &amp;lt;ThemeProvider theme={themes[selectedTheme]}&amp;gt;
          &amp;lt;GlobalStyle /&amp;gt;
          &amp;lt;Story /&amp;gt;
        &amp;lt;/ThemeProvider&amp;gt;
      &amp;lt;/AppRouterContext.Provider&amp;gt;
    &amp;lt;/QueryClientProvider&amp;gt;
  )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example: Button Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create the Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a new folder for the component at /src/components/button. Inside this folder, add the following file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/src/components/button/index.tsx&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// index.tsx

export default function Button({children, onClick, disabled}){
  return &amp;lt;button onClick={onClick} disabled={disabled}&amp;gt;{children}&amp;lt;/button&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Add Stories&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the same folder, create a file named Button.stories.ts to define the stories for the Button component.&lt;/p&gt;

&lt;p&gt;You can use diferents files [js|jsx|mjs|ts|tsx].&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/src/components/button/Button.stories.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Button.stories.ts

import type { Meta, StoryObj } from '@storybook/react'
import { fn } from '@storybook/test'

import Button from './'

const meta = {
  title: 'UI/Primary Button',
  component: Button,
  parameters: {
    layout: 'centered',
  },
  tags: ['autodocs'],
  argTypes: {},
  args: { onClick: fn() },
} satisfies Meta&amp;lt;typeof Button&amp;gt;

export default meta
type Story = StoryObj&amp;lt;typeof meta&amp;gt;

export const Primary: Story = {
  args: {
    children: 'Button',
    disabled: false,
  },
  parameters: {
    nextjs: {
      appDirectory: true,
    },
  },
}

export const Disabled: Story = {
  args: {
    children: 'Button Disabled',
    disabled: true,
  },
  parameters: {
    nextjs: {
      appDirectory: true,
    },
  },
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run and Build Storybook&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To build and run your Storybook environment, use the following commands:&lt;/p&gt;

&lt;p&gt;Build Storybook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  npm run build-storybook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run Storybook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  npm run storybook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, you can view Storybook's UI by opening it in your browser. After running npm run storybook, Storybook will be accessible at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:6006
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This interface allows you to browse, test, and document your components interactively. Enjoy exploring your UI components with Storybook! 🎉&lt;/p&gt;

&lt;p&gt;You should see something like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0w6xkzex0b48u76bgweg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0w6xkzex0b48u76bgweg.png" alt=" " width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>storybook</category>
      <category>nextjs</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Everything you need to know about Next.JS to start a new application today</title>
      <dc:creator>Layssa Lima</dc:creator>
      <pubDate>Tue, 03 Dec 2024 16:46:42 +0000</pubDate>
      <link>https://forem.com/layssadev/everything-you-need-to-know-about-nextjs-to-start-a-new-application-today-10ib</link>
      <guid>https://forem.com/layssadev/everything-you-need-to-know-about-nextjs-to-start-a-new-application-today-10ib</guid>
      <description>&lt;p&gt;1.  Introduction&lt;br&gt;
2.  The Project&lt;br&gt;
3.  Starting setup&lt;br&gt;
4.  Rounting&lt;br&gt;
5.  Project Routes&lt;br&gt;
6.  Navigating between pages&lt;br&gt;
7.  Conclusion&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Everything you need to know about Next.JS to start a new application today.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  1 Introduction
&lt;/h2&gt;

&lt;p&gt;Today, we’ll dive into building an application with Next.js!&lt;/p&gt;

&lt;p&gt;Next.js is a powerful React framework that goes beyond just front-end development. While React typically focuses on building user interfaces, Next.js enables full-stack applications by handling both the front end and back end in one unified framework. This approach is often referred to as a "Backend for Frontend" (BFF), allowing us to create complete, robust applications with ease.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Importants Links&lt;br&gt;
&lt;a href="https://github.com/Layssaa/learning-nextjs" rel="noopener noreferrer"&gt;Github Repository&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  2 The Project
&lt;/h2&gt;

&lt;p&gt;The goal of this project is to create an event website dedicated to ticket sales. This platform will offer tickets for various types of events and will feature four main pages: the login page, an event feed, the purchase process, and the order summary page. &lt;/p&gt;
&lt;h2&gt;
  
  
  3 Starting setup
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.JS 18.8 or later.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Creating project
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next this, will be show some questions for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This will be the name and folder name of your project.
What is your project named? eve

// **YES** - Use typescript is better, for this project, we will be use.
Would you like to use TypeScript? No / Yes

// **YES** - Eslint can help you to avoid errors
Would you like to use ESLint? No / Yes

// **NO** - For this project, we will use styled-components
Would you like to use Tailwind CSS? No / Yes

// **YES**
Would you like your code inside a `src/` directory? No / Yes

// **YES**
Would you like to use App Router? (recommended) No / Yes

// **NO**
Would you like to use Turbopack for `next dev`?  No / Yes

// **NO**
Would you like to customize the import alias (`@/*` by default)? No / Yes
What import alias would you like configured? @/*

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now you can run the command below to see the default Next.js page.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use this approach, but it will build your application as static pages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  npm run start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4 Rounting
&lt;/h2&gt;

&lt;p&gt;Next.js provides an easy way to handle routing in your application based on path names. Let’s take a closer look at each case.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Commom routing
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the /src/app directory, look for the page.tsx file. Every page file in Next.js is named this way, and you must always export it as the default. This is the default page displayed when you access ´&lt;a href="http://localhost:3000%C2%B4" rel="noopener noreferrer"&gt;http://localhost:3000´&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now, let’s create a new route: inside the src/app directory, create a folder called auth. Within this folder, create a file named page.tsx. In this file, let’s add a simple div element with the text "login&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function Auth() {
  return &amp;lt;div&amp;gt;login&amp;lt;/div&amp;gt;;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you access "&lt;a href="http://localhost:3000/auth" rel="noopener noreferrer"&gt;http://localhost:3000/auth&lt;/a&gt;" you need see only this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07ht41j14vhiyy3q4q5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07ht41j14vhiyy3q4q5z.png" alt=" " width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2 - &lt;a href="https://nextjs.org/docs/app/building-your-application/routing/route-groups" rel="noopener noreferrer"&gt;Grouping Routes&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Sometimes we need to separate our code in more paths, but dont wanna change de url. &lt;/p&gt;

&lt;p&gt;Change the 'auth' path to '(auth)' and create a path inside calls 'login' and move the last file to them.&lt;/p&gt;

&lt;p&gt;Check two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the '/auth' url not working now, if you try access a 404 error will show you.&lt;/li&gt;
&lt;li&gt;if you access '/login' you will see our component.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So this help us to create modules in the project without interfering with the user experience.&lt;/p&gt;

&lt;h4&gt;
  
  
  4 - &lt;a href="https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes" rel="noopener noreferrer"&gt;Dynamic Routes&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;For a dynamic page, such as a product sales page, the layout should adapt to the product's specific information. In this case, details like the product name and price vary for each product. &lt;/p&gt;

&lt;p&gt;We achieve this by using a product ID to fetch the relevant information, typically obtained from the URL.&lt;/p&gt;

&lt;p&gt;To implement this, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inside /app, create a folder named events.&lt;/li&gt;
&lt;li&gt;Inside the events folder, create another folder named [id]—the brackets indicate a dynamic route for the product ID.&lt;/li&gt;
&lt;li&gt;Inside the [id] folder, create a file named page.tsx.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In page.tsx add this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'use client' //&amp;lt;- this is important, because whe are using a hook
//so we need to inform its a client side
import { useParams } from "next/navigation";

export default function EventInfo() {
    const params = useParams(); // get url params

    return &amp;lt;div&amp;gt;{params.id}&amp;lt;/div&amp;gt;;
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can access '/events/111' and see this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9josvihirw9a7rgukpi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9josvihirw9a7rgukpi.png" alt=" " width="543" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7 Project Routes
&lt;/h2&gt;

&lt;p&gt;We already know the basics features to start our development, so let's get started intalling the dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i styled-components react-query 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Creating authentication pages
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Auth routes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inside '(auth)' path create a "register", your path must looks likes this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahebqk6c8mhgjy671fsv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahebqk6c8mhgjy671fsv.png" alt=" " width="291" height="101"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Platform routes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inside 'app' path create a "platform"&lt;br&gt;
Inside "platform" create "[id]"&lt;br&gt;
Inside "platform" create "purchase"&lt;/p&gt;

&lt;p&gt;Your path must looks likes this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcff3855iwfrfi21tgq5n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcff3855iwfrfi21tgq5n.png" alt=" " width="207" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this step you can create genericals pages, this articles is focus on nextjs features.&lt;/p&gt;
&lt;h2&gt;
  
  
  7 Project Routes - &lt;a href="https://nextjs.org/docs/app/building-your-application/routing/middleware" rel="noopener noreferrer"&gt;Middlewares&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;In our project, there are publics routers and privates routers, to protect and control the access, we need learn about middlewares.&lt;/p&gt;

&lt;p&gt;Middlewares is a function that will be execute in every load page and to configure this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;At 'src' path create middleware.ts&lt;/li&gt;
&lt;li&gt;Inside the file add this code.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export default function middleware(request: NextRequest) {
  return NextResponse.redirect(new URL('/home', request.url))
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Still inside this file, create 2 arrays
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Only authenticated access
const protectedRoutes = ["/platform"];

const publicRoutes = ["/login", "/register"];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Inside middleware function, we will verify the router rule and user session.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export function middleware(request: NextRequest) {
  // URL ACESSED
  const { pathname } = request.nextUrl;
  // USER SESSION
  const userId = request.cookies.get("user-id");

  // FUNCTION TO VERIFY IF IS A PROTECTED ROUTER
  const isPrivateRouter = protectedRoutes.some((path: string) =&amp;gt;
    pathname.startsWith(path)
  );

  if (isPrivateRouter &amp;amp;&amp;amp; userId) {
    return NextResponse.next();
  }

  if (isPrivateRouter &amp;amp;&amp;amp; !userId) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  // FUNCTION TO VERIFY IF IS A PUBLIC ROUTER
  const isPublicRouter = publicRoutes.some((path: string) =&amp;gt;
    pathname.startsWith(path)
  );

  if (isPublicRouter &amp;amp;&amp;amp; !userId) {
    return NextResponse.next();
  }

  if (isPublicRouter &amp;amp;&amp;amp; userId) {
    return NextResponse.redirect(new URL("/platform", request.url));
  }

  // REDIRECT TO LOGIN IF URL IS INVALID
  return NextResponse.redirect(new URL("/login", request.url));
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you dont wanna execute the middleware in especifics routers, you can add in the same file this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const config = {
  matcher: ['/login'],
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7 Navigating between pages
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;In this step, disable the middleware.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffx3ex88vcwl5j1yx2b07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffx3ex88vcwl5j1yx2b07.png" alt=" " width="493" height="130"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To navigate between pages we must to use two ways.&lt;/p&gt;

&lt;p&gt;When is a link options, the next component is the better instead the default html tag, because don't re rendering a page and causing a new pre render on server, and the Next Link component doesn't.&lt;/p&gt;

&lt;p&gt;For example, create a button at login page for navigate to inside the platform.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnkast070ky96jbxlkljp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnkast070ky96jbxlkljp.png" alt=" " width="422" height="162"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you click at button, you will see a re render page.&lt;/p&gt;

&lt;p&gt;So let's try to use the next component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6fdcg37qgmpg2u42zq48.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6fdcg37qgmpg2u42zq48.png" alt=" " width="479" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigating like that, do you have a SPA (A SINGLE PAGE APPLICATION), that's  made a better user experience.&lt;/p&gt;

&lt;p&gt;Another way to do the same thing is using a router hook from next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd29gc7kr3aov73jkw6g6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd29gc7kr3aov73jkw6g6.png" alt=" " width="662" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we explored key Next.js features, including the fundamentals of routing, creating dynamic and nested pages, organizing code with route groups, and implementing authentication and access control using middleware. Additionally, we learned how to optimize navigation for a better user experience by leveraging the Link component and programmatic routing with the useRouter hook. These concepts lay a strong foundation for building scalable and user-friendly applications with Next.js&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>web</category>
      <category>webdev</category>
      <category>website</category>
    </item>
    <item>
      <title>O que é o Nginx?</title>
      <dc:creator>Layssa Lima</dc:creator>
      <pubDate>Fri, 07 Apr 2023 20:59:33 +0000</pubDate>
      <link>https://forem.com/layssadev/o-que-e-o-nginx-1kh0</link>
      <guid>https://forem.com/layssadev/o-que-e-o-nginx-1kh0</guid>
      <description>&lt;h2&gt;
  
  
  O que é o Nginx?
&lt;/h2&gt;

&lt;p&gt;O Nginx inicialmente foi construído para ser usado como servidor web, em resposta a um problema chamado C10K, esse problema era gerenciar 10 mil conexões simultâneas. Todavia, dado o desempenho ao longo do tempo, a ferramenta foi aumentando as funcionalidades, atuando hoje como: webserver, load balancer, proxy reverso, media streaming, além de proxy para serviços de e-mail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como ele funciona?
&lt;/h2&gt;

&lt;p&gt;Hoje o Nginx é um dos servidores mais seguros e escaláveis por usar conexão orientada a eventos e assíncrona. E o que isso significa?&lt;/p&gt;

&lt;p&gt;Ele usa o funcionamento de single thread para as requisições recebidas, explicarei logo abaixo, de maneira que pouca memória é necessária.&lt;/p&gt;

&lt;p&gt;Ok, mas o que é a single thread?&lt;br&gt;
Analise a imagem abaixo, o nginx possui uma fila de processos, chamada &lt;em&gt;Thread Master&lt;/em&gt;, essa por sua vez gerencia os &lt;em&gt;workers&lt;/em&gt;, que são os responsáveis por de fato executar a tarefas, onde cada um é alocado em núcleos de processamentos da máquina.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw6bb18g3yu7g101a5jfd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw6bb18g3yu7g101a5jfd.png" alt=" " width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora que entendemos as divisões de tarefas dos núcleos, precisamos entender o porquê do nginx ser assíncrono e orientado a eventos. &lt;/p&gt;

&lt;p&gt;Veja bem, imagine um servidor que recebe 100 requisições por segundo, onde o tempo de resposta varie e não sabemos ao certo quando o processamento irá ser finalizado. Nesse cenário, não podemos travar o servidor, impedindo que ele receba novas requisições, logo, enquanto uma tarefa X aguarda resposta, outras são resolvidas simultaneamente. Note que aqui encontramos mais uma característica do server, ele não faz com que uma tarefa seja bloqueada em detrimento de outra, há uma reorientação de recursos enquanto aguarda resposta, isso é possível porque é criado um canal de escuta que avisará quando tudo estiver concluído, sendo assim, orientado a eventos.&lt;/p&gt;

&lt;p&gt;Você pode ler um pouco mais sobre isso &lt;a href="https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>nginx</category>
    </item>
  </channel>
</rss>
