Desenvolvimento

19 nov, 2018

Criando um jogo baseado em texto com o Twine

Publicidade

Sempre me envolvi com programação e o ensino dela (por isso fundei uma escola especializada chamada Code Prestige para jovens iniciantes na área até pessoas de maior nível de senioridade). No entanto, recentemente comecei a minha jornada sob uma outra perspectiva: ensino de programação para crianças.

Se você acha que programar é complicado, imagine o quão abstrato para as crianças conceitos como orientação a objetos, funções, variáveis, loops, debug, etc, são.

Então, para começar de forma mais tranquila a introduzir o pensamento computacional na cabeça destes pequenos, comecei a trabalhar com jogos de tabuleiro e jogos digitais. Feito isso, passamos para uma nova fase: produzir jogos digitais.

Para que uma criança consiga assimilar tantos conceitos e produza algo intangível, precisamos de abordagens criativas. Foi na busca desta abordagem que me deparei com o Twine, uma excelente ferramenta para a criação de jogos baseados em texto.

Jogos baseados em texto

Esse tipo de jogo antecedeu os jogos de apontar e clicar e foram uma grande febre quando surgiram. A ideia é extremamente simples: apresentamos ao jogador um contexto sobre o universo em que o jogo está inserido, e então damos uma narrativa que é controlada pelo jogador. A cada opção selecionada pelo jogador, a história é direcionada para um caminho específico, no final resultando em múltiplas possibilidades de finais.

Se você é fã deste tipo de gênero, já deve ter experimentado jogos atuais como Heavy Rain, Beyond: Two Souls e o mais recente, Detroit: Become Human. Apesar de serem jogos muito bem trabalhados nos seus modelos tridimensionais, trilhas sonoras, jogabilidade e afins; seu principal elemento continua sendo a narrativa baseada em escolhas, herança do tipo de jogo que estamos discutindo.

Só que mesmo sendo um jogo simples, o esforço para programá-lo em tecnologias atuais é muito maior do que as crianças são capazes de fazer hoje. Mas com o Twine tudo ficou bem mais simples e direto.

Criando jogos baseados em texto

O Twine é uma ferramenta de código aberto desenvolvida originalmente em 2009, pelo engenheiro de software Chris Klimas com objetivo de criar uma maneira fácil de contar histórias interativas e não lineares.

A aplicação possui versões que podem ser instaladas no Windows, Linux e Mac; mas há também uma versão web disponível neste link.

Cada jogo criado na plataforma é chamado de “História”. Podemos criar uma nova clicando no botão “+ História” no menu vertical do lado direito do site.

Criando uma nova história no Twine

Após inserir um novo nome para a história, somos redirecionados para um plano cartesiano. É nesta tela que vamos desenhar todo o resto do jogo. Cada passo do jogo é definido de forma bem intuitiva, através do bloco chamado de passagem. O jogo começa com uma passagem inicial:

Passagem inicial no Twiner

Ao dar um duplo clique na passagem, um modal se abrirá e é lá onde vamos inserir os comandos do jogo. O texto digitado é exibido normalmente, mas para inserir “links” (e quando digo link, entenda como as escolhas que iremos oferecer ao jogador), usamos a seguinte sintaxe:

[[<ação> -> <nome_da_passagem>]]

Para entender melhor o que isso quer dizer, partiremos para um exemplo mais prático. Considere que na passagem inicial a gente insira o seguinte roteiro:

Você está com sede. Do lado direito, há uma lanchonete e do lado esquerdo um lago. Para onde você vai?

[[vou para a lanchonete -> lanchonete]]

[[vou para o lago -> lago]]

Esse jogo será reproduzido na seguinte maneira no mapa.

Passagem com duas escolhas

Bem legal, né? Agora, já podemos testar o nosso jogo. Para isso, existem duas opções possíveis:

  • Testar: o jogo é executado em modo de debug. Aqui temos uma visualização de variáveis e fluxos em tempo de execução.
  • Jogar: o jogo é executado como se você fosse um jogador normal.

Ao clicar em qualquer uma das opções, o jogo vai abrir em um outra aba do navegador.

E de maneira simples assim, conseguimos fazer o nosso jogo!

Conclusão

O funcionamento do Twiner é bem simples. No entanto, sua API nos possibilita uma verdadeira infinidade de opções para o nosso jogo. Desde condicionais, loops, estruturas de dados, enfim – a ferramenta é extensa e bem completa. Vale a pena conferir!

Referências

 

)).required(),\r\n});\r\n\r\napp.post(\"\u002Fusers\", (req, res) => { \r\n const user = req.body; \r\n if(!username || !email || !year || !password) {\r\n return res.status(422).send(\"Incomplete data.\");\r\n }\r\n \r\n \u002F\u002F restante do código \r\n});\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"340f\" class=\"my mz ho na b nb nc nd ne nf ng nh ni fk nj nk nl fn nm nn no fq np nq nr ns pi pj pk bk\" data-selectable-paragraph=\"\"\u003EUsamos o \u003Ccode class=\"cx qa qb qc pr b\"\u003Ejoi.object()\u003C\u002Fcode\u003E para definir o schema e então usamos o \u003Ccode class=\"cx qa qb qc pr b\"\u003Estring()\u003C\u002Fcode\u003E, \u003Ccode class=\"cx qa qb qc pr b\"\u003Eemail()\u003C\u002Fcode\u003E, \u003Ccode class=\"cx qa qb qc pr b\"\u003Emin()\u003C\u002Fcode\u003E, \u003Ccode class=\"cx qa qb qc pr b\"\u003Emax()\u003C\u002Fcode\u003E, e assim por diante para fazer as validações necessárias.\u003C\u002Fli\u003E\n\u003Cli id=\"3e63\" class=\"my mz ho na b nb pl nd ne nf pm nh ni fk pn nk nl fn po nn no fq pp nq nr ns pi pj pk bk\" data-selectable-paragraph=\"\"\u003EAgora, ao invés de ficar encadeando ifs e elses, simplesmente usamos esse objeto de referência para validar a informação que o usuário nos enviou:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-javascript\"\u003Eimport joi from \"joi\";\r\n\r\nconst userSchema = joi.object({\r\n username: joi.string().min(3).max(10).required(),\r\n email: joi.string().email().required(),\r\n year: joi.number().integer().min(1900).max(2024).required(),\r\n password: joi.string().pattern(new RegExp('^[a-zA-Z0-9]{3,30} window.__SERVER_VARS__ = {"applicationRestUrl":"https:\u002F\u002Fadmin.imasters.com.br\u002Fwp-json","applicationBaseUrl":"https:\u002F\u002Fadmin.imasters.com.br"} )).required(),\r\n});\r\n\r\napp.post(\"\u002Fusers\", (req, res) => { \r\n const user = req.body; \r\n const validation = userSchema.validate(user, { abortEarly: false });\r\n if (validation.error) {\r\n const errors = validation.error.details.map(detail => detail.message)\r\n return res.status(422).send(errors)\r\n }\r\n \r\n \u002F\u002F restante do código \r\n});\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Ch3 id=\"1192\" class=\"qd os ho bf ot qe qf qg fg qh qi qj fj qk ql qm qn qo qp qq qr qs qt qu qv qw bk\"\u003ERepositório\u003C\u002Fh3\u003E\n\u003Cp id=\"b72d\" class=\"pw-post-body-paragraph my mz ho na b nb pa nd ne nf pb nh ni fk pc nk nl fn pd nn no fq pe nq nr ns gp bk\" data-selectable-paragraph=\"\"\u003E\u003Ca class=\"ag pz\" href=\"https:\u002F\u002Fgithub.com\u002FProfessor-DiegoPinho\u002Fvalidacao-joi\" target=\"_blank\" rel=\"noopener ugc nofollow noreferrer\"\u003Ehttps:\u002F\u002Fgithub.com\u002FProfessor-DiegoPinho\u002Fvalidacao-joi\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n","excerpt":"\u003Cp\u003EPara garantir o funcionamento correto das nossas APIs e evitar problemas é super importante sempre validar a entrada dos nossos usuários. No entanto…\u003C\u002Fp\u003E\n","link":"https:\u002F\u002Fimasters.com.br\u002Fapis-microsservicos\u002Fvalidacoes-mais-eficazes-na-sua-api-com-a-biblioteca-joi","date":"7 jul, 2025","thumbnail":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F07\u002F26183954\u002FAPIs.jpg","externalMention":null,"author":{"id":144418,"thumbnail":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2018\u002F05\u002F30171243\u002Fdiego-pinho.jpg","name":"Diego Pinho","description":"Bacharel em Ciência da Computação pela PUCSP e MBA em Gestão da Tecnologia da Informação na FIAP. Autor do livro ECMAScript 6 - Entre de cabeça no futuro do JavaScript. Cofundador da Code Prestige e Community Manager no iMasters.","slug":"diegopinho","url":"https:\u002F\u002Fimasters.com.br\u002Fperfil\u002Fdiegopinho","registered":"2013-08-13 18:00:53","social":{"linkedin":null,"youtube":null,"facebook":"","twitter":"https:\u002F\u002Ftwitter.com\u002FDiegoPinho","instagram":null,"github":null,"url":"http:\u002F\u002Fwww.diegopinho.com.br","mail":"diego.pinho@imasters.com.br"},"articles_count":113,"views_count":1276900,"certifications":null,"conquests":null,"office":null},"categories":[{"title":"APIs e Microsserviços","slug":"apis-microsservicos","id":4257,"link":"https:\u002F\u002Fimasters.com.br\u002Fapis-microsservicos"},{"title":"JavaScript","slug":"javascript","id":7220,"link":"https:\u002F\u002Fimasters.com.br\u002Fjavascript"}],"tags":[{"title":"api","slug":"api","id":187,"link":"https:\u002F\u002Fimasters.com.br\u002Fapi"},{"title":"javascript","slug":"javascript-2","id":214,"link":"https:\u002F\u002Fimasters.com.br\u002Fjavascript-2"},{"title":"node","slug":"node","id":236,"link":"https:\u002F\u002Fimasters.com.br\u002Fnode"},{"title":"nodejs","slug":"nodejs","id":3153,"link":"https:\u002F\u002Fimasters.com.br\u002Fnodejs"}],"seo":{"open_graph":{"title":"Validações mais felizes na sua API com a biblioteca Joi","description":"Para garantir o funcionamento correto das nossas APIs e evitar problemas é super importante sempre validar a entrada dos nossos usuários. No entanto...","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":{"src":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F07\u002F26183954\u002FAPIs.jpg","width":800,"height":533},"modified_time":"2025-07-07T13:15:10-03:00","published_time":"2025-07-07T09:24:22-03:00"},"twitter":{"title":"Validações mais felizes na sua API com a biblioteca Joi","description":"Para garantir o funcionamento correto das nossas APIs e evitar problemas é super importante sempre validar a entrada dos nossos usuários. No entanto...","type":"summary_large_image","image":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F07\u002F26183954\u002FAPIs.jpg"}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fapis-microsservicos\u002Fvalidacoes-mais-eficazes-na-sua-api-com-a-biblioteca-joi","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fapis-microsservicos\u002Fvalidacoes-mais-eficazes-na-sua-api-com-a-biblioteca-joi","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fapis-microsservicos\u002Fvalidacoes-mais-eficazes-na-sua-api-com-a-biblioteca-joi"},"type":"post"},{"id":163616,"title":"Arquitetura de Microsserviços em Node com o MoleculerJS","content":"\u003Cp id=\"618f\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EMontar um projeto na arquitetura de Microsserviços não é tão trivial e nem tão necessário quanto a maior parte das pessoas desenvolvedoras iniciantes imaginam que seja.\u003C\u002Fp\u003E\n\u003Cp id=\"c011\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EMuitos escutam o termo e, por ele estar na moda, já acham que precisam sair aplicando sem mesmo entender o que ela é, pra que serve e porque faria sentido (ou não) usá-la. Na vida real não é bem assim que funciona.\u003C\u002Fp\u003E\n\u003Cp id=\"4768\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EA arquitetura de microsserviços é incrível e pode resolver vários complexos. Mas aí é que está o X da questão: quais problemas complexos que ele resolve? Dificilmente um projeto pessoal pequeno terá qualquer tipo desses problemas.\u003C\u002Fp\u003E\n\u003Cp id=\"b8cd\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EO caminho natural das nossas aplicações é ser construída em um monolito até que faça sentido mudar a sua arquitetura. Isso se fizer sentido. Você sabia que o próprio \u003Ca class=\"ag or\" href=\"https:\u002F\u002Fstackoverflow.com\u002F\" target=\"_blank\" rel=\"noopener ugc nofollow noreferrer\"\u003E\u003Cstrong class=\"ny hp\"\u003EStack Overflow\u003C\u002Fstrong\u003E\u003C\u002Fa\u003E é um monolito?\u003C\u002Fp\u003E\n\u003Cp id=\"3c04\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EDito isso, estudar esse tipo de arquitetura e aplicá-la para aprender seus conceitos e detalhes é sim muito interessante. Experimentar um pouco dessa arquitetura te ajudará a ganhar experiência para então tomar melhores decisões no futuro.\u003C\u002Fp\u003E\n\u003Cp id=\"5472\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EComo então fazer para aplicar essa arquitetura dentro do ecossistema Node?\u003C\u002Fp\u003E\n\u003Cp id=\"c54b\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EComo tudo na tecnologia, há várias formas diferentes; no entanto, recentemente encontrei uma bem interessante por meio do framework \u003Ca class=\"ag or\" href=\"https:\u002F\u002Fmoleculer.services\u002Findex.html\" target=\"_blank\" rel=\"noopener ugc nofollow noreferrer\"\u003E\u003Cstrong class=\"ny hp\"\u003EMoleculer\u003C\u002Fstrong\u003E\u003C\u002Fa\u003E.\u003C\u002Fp\u003E\n\u003Cp id=\"1aaa\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EBora explorá-lo?\u003C\u002Fp\u003E\n\u003Cp id=\"1816\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003E—\u003C\u002Fp\u003E\n\u003Ch2 id=\"5fed\" class=\"os ot ho bf ou ov ow ox fg oy oz pa fj pb pc pd pe pf pg ph pi pj pk pl pm pn bk\"\u003E\u003Cspan style=\"font-size: 18pt;\"\u003EO Framework Moleculer\u003C\u002Fspan\u003E\u003C\u002Fh2\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"1b86\" class=\"nw nx ho ny b nz po ob oc od pp of og fk pq oi oj fn pr ol om fq ps oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003EO Moleculer é um framework para Node.js que nos ajuda a criar aplicações usando a arquitetura de microsserviços.\u003C\u002Fli\u003E\n\u003Cli id=\"2375\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003EAplicar a arquitetura de microsserviços não se resume a apenas quebrar a aplicação em várias menores. Existem conceitos e técnicas para conseguir fazer isso da melhor forma possível, e o framework já vem integrado com vários deles, como por exemplo:\u003C\u002Fli\u003E\n\u003Cli id=\"185e\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003EAPI Gateway;\u003C\u002Fli\u003E\n\u003Cli id=\"4a5b\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003ELoad Balancer;\u003C\u002Fli\u003E\n\u003Cli id=\"b5be\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003EFault Tolerance;\u003C\u002Fli\u003E\n\u003Cli id=\"d3d4\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003EService Discovery;\u003C\u002Fli\u003E\n\u003Cli id=\"3499\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003EEtc.\u003C\u002Fli\u003E\n\u003Cli id=\"1473\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003ENão vale a pena ficar explicando cada um desses pontos agora porque esse assunto é bem denso. Vamos tentar montar um projetinho na prática com essa arquitetura e naturalmente descobriremos o que eles são e como usá-los.\u003C\u002Fli\u003E\n\u003Cli id=\"9209\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003ECombinado?\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Ch3 id=\"06b7\" class=\"os ot ho bf ou ov ow ox fg oy oz pa fj pb pc pd pe pf pg ph pi pj pk pl pm pn bk\"\u003E\u003Cspan style=\"font-size: 18pt;\"\u003EAplicação prática\u003C\u002Fspan\u003E\u003C\u002Fh3\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"073b\" class=\"nw nx ho ny b nz po ob oc od pp of og fk pq oi oj fn pr ol om fq ps oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003EComo eu disse, o caminho natural de uma aplicação é nascer do monolito e, a medida que sua complexida se tornar muito grande, a “quebramos” em aplicações menores.\u003C\u002Fli\u003E\n\u003Cli id=\"effd\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003EPartindo dessa ideia, vamos começar da seguinte aplicação:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cfigure class=\"pt pu pv pw px my nh ni paragraph-image\"\u003E\n\u003Cdiv class=\"nr ns ee nt bh nu\" tabindex=\"0\" role=\"button\"\u003E\n\u003Cdiv class=\"nh ni qj\"\u003E\u003Cpicture\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002Fformat:webp\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002Fformat:webp\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002Fformat:webp\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002Fformat:webp\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002Fformat:webp\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002Fformat:webp\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1400\u002Fformat:webp\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 1400w\" type=\"image\u002Fwebp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \u002F\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1400\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \u002F\u003E\u003Cimg class=\"bh er nv c\" role=\"presentation\" src=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:875\u002F1*1TQQGby6-h2XcRy6WKVG-Q.png\" alt=\"\" width=\"700\" height=\"442\" \u002F\u003E\u003C\u002Fpicture\u003E\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\n\u003C\u002Ffigure\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"66c2\" class=\"nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003EPara a coisa não ficar muito complexa, existem apenas três rotas: uma para criação de usuário, outra para fazer o usuário entrar na aplicação e uma terceira rota protegida (exige autenticação).\u003C\u002Fli\u003E\n\u003Cli id=\"2d8a\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003EVou propor separamos essa aplicação em dois microsserviços distintos, uma para cuidar da parte de criação, cadastro e login dos usuários; e o outra para lidar com os produtos.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cfigure class=\"pt pu pv pw px my nh ni paragraph-image\"\u003E\n\u003Cdiv class=\"nr ns ee nt bh nu\" tabindex=\"0\" role=\"button\"\u003E\n\u003Cdiv class=\"nh ni qk\"\u003E\u003Cpicture\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002Fformat:webp\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002Fformat:webp\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002Fformat:webp\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002Fformat:webp\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002Fformat:webp\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002Fformat:webp\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1400\u002Fformat:webp\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 1400w\" type=\"image\u002Fwebp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \u002F\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1400\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \u002F\u003E\u003Cimg class=\"bh er nv c\" role=\"presentation\" src=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:875\u002F1*WSIfVlPjzoM7c0V9IkWegQ.png\" alt=\"\" width=\"700\" height=\"313\" \u002F\u003E\u003C\u002Fpicture\u003E\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\n\u003C\u002Ffigure\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"c8ab\" class=\"nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003ENote que em um arquitetura em microsserviços temos uma interface que centralizará todas as requisições e “distribuirá” para os respectivos serviços. Aqui ela está representada pelo app no diagrama. Esta peça é o que chamamos de \u003Cstrong class=\"ny hp\"\u003EGateway\u003C\u002Fstrong\u003E.\u003C\u002Fli\u003E\n\u003Cli id=\"a283\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003ERepare também que nesta organização, cada aplicação tem o seu próprio banco de dados. A ideia é que os serviços sejam independentes, até mesmo nos dados. Mas nada impede que essas aplicações se comuniquem.\u003C\u002Fli\u003E\n\u003Cli id=\"451a\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003EEssa comunicação pode acontecer de várias formas, desde chamadas http (pouco usado) até serviços de mensageria (muito usado). Em nossa aplicação usaremos um serviço externo chamado \u003Ca class=\"ag or\" href=\"https:\u002F\u002Fnats.io\u002F\" target=\"_blank\" rel=\"noopener ugc nofollow noreferrer\"\u003E\u003Cstrong class=\"ny hp\"\u003ENATS\u003C\u002Fstrong\u003E\u003C\u002Fa\u003E que vai nos ajudar com isso.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp id=\"1ee4\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EPara começar a implementação, faremos 3 projetos em node (farei na mesma pasta pra facilitar):\u003C\u002Fp\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"491e\" class=\"nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003Eapi-gateway: \u003Ccode class=\"cx ql qm qn qo b\"\u003Enpm i moleculer moleculer-web nats\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli id=\"81c9\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003Eauth-service: \u003Ccode class=\"cx ql qm qn qo b\"\u003Enpm i moleculer moleculer-replt nats uuid\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli id=\"e911\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003Eproduct-service: \u003Ccode class=\"cx ql qm qn qo b\"\u003Enpm i moleculer moleculer-replt nats\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp id=\"185b\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EVamos começar a construção de cada uma das peças da nossa aplicação.\u003C\u002Fp\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"fa2f\" class=\"nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003E\u003Cstrong\u003EAPI Gateway\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-c\"\u003Eimport { ServiceBroker } from \"moleculer\";\r\nimport ApiGatewayService from \"moleculer-web\";\r\n\r\nconst broker = new ServiceBroker({\r\n nodeID: \"gateway-node\",\r\n transporter: \"NATS\",\r\n});\r\n\r\nbroker.createService({\r\n name: \"gateway\",\r\n mixins: [ApiGatewayService],\r\n settings: {\r\n port: 5000,\r\n routes: [\r\n {\r\n path: \"\u002Fauth\",\r\n aliases: {\r\n \"POST \u002Fsign-up\": \"auth.signUp\",\r\n \"POST \u002Fsign-in\": \"auth.signIn\"\r\n }\r\n },\r\n {\r\n path: \"\u002Fapi\",\r\n bodyParsers: {\r\n json: true,\r\n urlencoded: { extended: true }\r\n },\r\n authorization: true,\r\n aliases: {\r\n \"GET \u002Fproducts\": \"product.getProducts\"\r\n }\r\n }\r\n ]\r\n },\r\n methods: {\r\n async authorize(ctx, route, req, res) {\r\n let auth = req.headers[\"authorization\"];\r\n if (auth && auth.startsWith(\"Bearer\")) {\r\n let token = auth.slice(7);\r\n\r\n const user = await ctx.call(\"auth.validateToken\", { token });\r\n if (!user.error) return Promise.resolve(ctx);\r\n\r\n return Promise.reject({ error: \"Token Inválido\" });\r\n\r\n } else {\r\n return Promise.reject({ error: \"Token Inválido\" });\r\n }\r\n }\r\n\r\n }\r\n});\r\n\r\nbroker.start();\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"6c57\" class=\"nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003E\u003Cstrong\u003EAuth Service\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-c\"\u003Eimport { ServiceBroker } from \"moleculer\";\r\nimport { v4 as uuidv4 } from 'uuid';\r\n\r\nconst users = [];\r\n\r\nconst broker = new ServiceBroker({\r\n nodeID: \"auth-service-node\",\r\n transporter: \"NATS\"\r\n});\r\n\r\nbroker.createService({\r\n name: \"auth\",\r\n actions: {\r\n signUp(ctx) {\r\n const { username, password } = ctx.params;\r\n users.push({\r\n username,\r\n password\r\n });\r\n\r\n return \"User created.\"\r\n },\r\n\r\n signIn(ctx) {\r\n const { username, password } = ctx.params;\r\n const user = users.find(user => user.username === username);\r\n if (user && user.password === password) {\r\n const token = uuidv4();\r\n user.token = token;\r\n return {\r\n token\r\n }\r\n }\r\n\r\n return { error: \"Invalid credentials\" }\r\n },\r\n\r\n validateToken(ctx) {\r\n const { token } = ctx.params;\r\n const user = users.find(user => user.token === token);\r\n if (!user) return { error: \"Invalid token.\" }\r\n\r\n return user;\r\n }\r\n }\r\n});\r\n\r\nbroker.start().then(() => {\r\n broker.repl();\r\n})\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"6bc3\" class=\"nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003E\u003Cstrong\u003EProducts Service\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-c\"\u003Eimport { ServiceBroker } from \"moleculer\";\r\n\r\nconst products = [\r\n { id: 1, name: \"PC da Xuxa\", price: 15000 }\r\n]\r\n\r\nconst broker = new ServiceBroker({\r\n nodeID: \"product-service-node\",\r\n transporter: \"NATS\"\r\n});\r\n\r\nbroker.createService({\r\n name: \"product\",\r\n actions: {\r\n getProducts(ctx) {\r\n return products;\r\n }\r\n }\r\n});\r\n\r\nbroker.start().then(() => {\r\n broker.repl();\r\n})\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"3f1e\" class=\"nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003EPara conseguir fazer os microsserviços conversarem, precisaremos no NATS!\u003C\u002Fli\u003E\n\u003Cli id=\"abc4\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003EA forma mais fácil de trazer ele pro jogo é por meio do Docker:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-c\"\u003Edocker run --name nats -p 4222:4222 nats\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp id=\"7957\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EE pronto! Temos nossa solução em microsserviços! 😄\u003C\u002Fp\u003E\n\u003Ch3 id=\"20d3\" class=\"qx ot ho bf ou fe qy ff fg fh qz fi fj fk ra fl fm fn rb fo fp fq rc fr fs rd bk\"\u003E💻 Repositório\u003C\u002Fh3\u003E\n\u003Cp id=\"b6e0\" class=\"pw-post-body-paragraph nw nx ho ny b nz po ob oc od pp of og fk pq oi oj fn pr ol om fq ps oo op oq gp bk\" data-selectable-paragraph=\"\"\u003E\u003Ca class=\"ag or\" href=\"https:\u002F\u002Fgithub.com\u002FProfessor-DiegoPinho\u002Fnode-microservice-moleculer\" target=\"_blank\" rel=\"noopener ugc nofollow noreferrer\"\u003Ehttps:\u002F\u002Fgithub.com\u002FProfessor-DiegoPinho\u002Fnode-microservice-moleculer\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Ch3 id=\"812d\" class=\"qx ot ho bf ou fe qy ff fg fh qz fi fj fk ra fl fm fn rb fo fp fq rc fr fs rd bk\"\u003E🌐 Referências e outros materiais\u003C\u002Fh3\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"2a97\" class=\"nw nx ho ny b nz po ob oc od pp of og fk pq oi oj fn pr ol om fq ps oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003E🌐 \u003Ca class=\"ag or\" href=\"https:\u002F\u002Fmoleculer.services\u002Findex.html\" target=\"_blank\" rel=\"noopener ugc nofollow noreferrer\"\u003EMoleculer — Progressive microservices framework for Node.js\u003C\u002Fa\u003E\u003C\u002Fli\u003E\n\u003Cli id=\"439b\" class=\"nw nx ho ny b nz qe ob oc od qf of og fk qg oi oj fn qh ol om fq qi oo op oq qb qc qd bk\" data-selectable-paragraph=\"\"\u003E🌐 \u003Ca class=\"ag or\" href=\"https:\u002F\u002Fnats.io\u002F\" target=\"_blank\" rel=\"noopener ugc nofollow noreferrer\"\u003ENATS.io — Cloud Native, Open Source, High-performance Messaging\u003C\u002Fa\u003E\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Ch3 id=\"0bf8\" class=\"os ot ho bf ou ov ow ox fg oy oz pa fj pb pc pd pe pf pg ph pi pj pk pl pm pn bk\"\u003EVersão em vídeo\u003C\u002Fh3\u003E\n\u003Cp id=\"fa19\" class=\"pw-post-body-paragraph nw nx ho ny b nz po ob oc od pp of og fk pq oi oj fn pr ol om fq ps oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EConfira a versão em vídeo desse artigo!\u003C\u002Fp\u003E\n\u003Cfigure class=\"pt pu pv pw px my\"\u003E\n\u003Cdiv class=\"py es m ee\"\u003E\n\u003Cdiv class=\"pz qa m\"\u003E\u003Ciframe class=\"eo o he dz bh\" title=\"Microsserviços em Node com o Moleculer.js\" src=\"https:\u002F\u002Fcdn.embedly.com\u002Fwidgets\u002Fmedia.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FLT9_51k-gxM%3Ffeature%3Doembed&display_name=YouTube&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DLT9_51k-gxM&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FLT9_51k-gxM%2Fhqdefault.jpg&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=youtube\" width=\"854\" height=\"480\" frameborder=\"0\" scrolling=\"no\" allowfullscreen=\"allowfullscreen\" data-mce-fragment=\"1\"\u003E\u003C\u002Fiframe\u003E\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\n\u003C\u002Ffigure\u003E\n\u003Cp id=\"e663\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003E—\u003C\u002Fp\u003E\n\u003Ch1 id=\"5fed\" class=\"os ot ho bf ou ov ow ox fg oy oz pa fj pb pc pd pe pf pg ph pi pj pk pl pm pn bk\" data-selectable-paragraph=\"\"\u003E\u003C\u002Fh1\u003E\n","excerpt":"\u003Cp\u003EMontar um projeto na arquitetura de Microsserviços … ecossistema Node? Como tudo na tecnologia, há várias formas diferentes; no… framework Moleculer.\u003C\u002Fp\u003E\n","link":"https:\u002F\u002Fimasters.com.br\u002Fjavascript\u002Farquitetura-de-microsservicos-em-node-com-o-moleculerjs","date":"23 jun, 2025","thumbnail":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F06\u002F26181751\u002FMicrosservi%C3%A7os.jpg","externalMention":null,"author":{"id":144418,"thumbnail":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2018\u002F05\u002F30171243\u002Fdiego-pinho.jpg","name":"Diego Pinho","description":"Bacharel em Ciência da Computação pela PUCSP e MBA em Gestão da Tecnologia da Informação na FIAP. Autor do livro ECMAScript 6 - Entre de cabeça no futuro do JavaScript. Cofundador da Code Prestige e Community Manager no iMasters.","slug":"diegopinho","url":"https:\u002F\u002Fimasters.com.br\u002Fperfil\u002Fdiegopinho","registered":"2013-08-13 18:00:53","social":{"linkedin":null,"youtube":null,"facebook":"","twitter":"https:\u002F\u002Ftwitter.com\u002FDiegoPinho","instagram":null,"github":null,"url":"http:\u002F\u002Fwww.diegopinho.com.br","mail":"diego.pinho@imasters.com.br"},"articles_count":113,"views_count":1276900,"certifications":null,"conquests":null,"office":null},"categories":[{"title":"JavaScript","slug":"javascript","id":7220,"link":"https:\u002F\u002Fimasters.com.br\u002Fjavascript"}],"tags":[{"title":"javascript","slug":"javascript-2","id":214,"link":"https:\u002F\u002Fimasters.com.br\u002Fjavascript-2"},{"title":"microservices","slug":"microservices","id":4156,"link":"https:\u002F\u002Fimasters.com.br\u002Fmicroservices"},{"title":"microserviços","slug":"microservicos","id":5632,"link":"https:\u002F\u002Fimasters.com.br\u002Fmicroservicos"},{"title":"MoleculerJS","slug":"moleculerjs","id":9240,"link":"https:\u002F\u002Fimasters.com.br\u002Fmoleculerjs"},{"title":"node","slug":"node","id":236,"link":"https:\u002F\u002Fimasters.com.br\u002Fnode"},{"title":"web","slug":"web","id":327,"link":"https:\u002F\u002Fimasters.com.br\u002Fweb"}],"seo":{"open_graph":{"title":"Arquitetura de Microsserviços em Node com o MoleculerJS","description":"Montar um projeto na arquitetura de Microsserviços ... ecossistema Node? Como tudo na tecnologia, há várias formas diferentes; no... framework Moleculer.","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":{"src":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F06\u002F26181751\u002FMicrosservi%C3%A7os.jpg","width":800,"height":533},"modified_time":"2025-05-26T18:31:02-03:00","published_time":"2025-06-23T09:21:06-03:00"},"twitter":{"title":"Arquitetura de Microsserviços em Node com o MoleculerJS","description":"Montar um projeto na arquitetura de Microsserviços ... ecossistema Node? Como tudo na tecnologia, há várias formas diferentes; no... framework Moleculer.","type":"summary_large_image","image":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F06\u002F26181751\u002FMicrosservi%C3%A7os.jpg"}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fjavascript\u002Farquitetura-de-microsservicos-em-node-com-o-moleculerjs","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fjavascript\u002Farquitetura-de-microsservicos-em-node-com-o-moleculerjs","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fjavascript\u002Farquitetura-de-microsservicos-em-node-com-o-moleculerjs"},"type":"post"},{"id":163608,"title":"Dica de ouro: Saiba como fazer uma navbar responsiva","content":"\u003Cp id=\"7c4b\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EHoje é praticamente impossível ter um site que não seja responsivo.\u003C\u002Fp\u003E\n\u003Cp id=\"2d82\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EExistem várias formas criativas e técnicas de lidar com responsividade (ex: Flexbox, Media Queries, CSS Grid, etc.) nos mais diferentes contextos, mas há algumas adaptações que são praticamente padrões em todos os projetos.\u003C\u002Fp\u003E\n\u003Cp id=\"27d9\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EUm claro exemplo é a navbar responsiva. Quando ela possui muitos itens, inevitavelmente se torna imprópria para o ambiente mobile, pois os itens literalmente não cabem no espaço disponível.\u003C\u002Fp\u003E\n\u003Cp id=\"1f21\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003ENessas situações, precisamos pensar em técnicas criativas. Hoje vamos aprender como fazer uma navbar responsiva minimalista e elegante usando apenas o básico HTML, CSS e um pouquinho de nada de JavaScript.\u003C\u002Fp\u003E\n\u003Cp id=\"53d7\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EPara aprendemos como fazer isso, tomaremos como exemplo a solução que apliquei no meu próprio site pessoal. Sou suspeito pra falar, mas acho que ela atendeu bem ao seu objetivo 😄\u003C\u002Fp\u003E\n\u003Cfigure class=\"os ot ou ov ow my nh ni paragraph-image\"\u003E\n\u003Cdiv class=\"nr ns ee nt bh nu\" tabindex=\"0\" role=\"button\"\u003E\n\u003Cdiv class=\"nh ni or\"\u003E\n\u003Cpicture\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002Fformat:webp\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002Fformat:webp\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002Fformat:webp\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002Fformat:webp\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002Fformat:webp\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002Fformat:webp\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1400\u002Fformat:webp\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 1400w\" type=\"image\u002Fwebp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \u002F\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1400\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \u002F\u003E\u003C\u002Fpicture\u003E\n\u003Cfigure style=\"width: 700px\" class=\"wp-caption alignnone\"\u003E\u003Cimg class=\"bh er nv c\" role=\"presentation\" src=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:875\u002F1*Gzqr6rb7ZM4yV7ZmdQnghg.gif\" alt=\"\" width=\"700\" height=\"405\" \u002F\u003E\u003Cfigcaption class=\"wp-caption-text\"\u003Efuncionamento da navbar responsiva\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\n\u003C\u002Ffigure\u003E\n\u003Cp id=\"f015\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EVamos começar criando a estrutura básica do site para desktop. Neste caso, precisamos essencialmente de três elementos HTML: uma tag <nav> para a barra de navegação, uma tag <img> para o logotipo e tags <ul> e <li> para a lista de links:\u003C\u002Fp\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-html\"\u003E<!DOCTYPE html>\r\n<html lang=\"pt-br\">\r\n\r\n<head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>Menu Responsivo<\u002Ftitle>\r\n <link rel=\"stylesheet\" href=\"style.css\">\r\n<\u002Fhead>\r\n\r\n<body>\r\n <nav class=\"navbar\">\r\n <img src=\"logo.png\" alt=\"logo\">\r\n <div class=\"navbar-links\">\r\n <ul>\r\n <li><a href=\"#\">Home<\u002Fa><\u002Fli>\r\n <li><a href=\"#\">Sobre<\u002Fa><\u002Fli>\r\n <li><a href=\"#\">Contato<\u002Fa><\u002Fli>\r\n <\u002Ful>\r\n <\u002Fdiv>\r\n <\u002Fnav>\r\n<\u002Fbody>\r\n\r\n<\u002Fhtml>\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp\u003EVamos aplicar o CSS básico para que ele funcione bem no desktop:\u003C\u002Fp\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-css\"\u003E@import url('https:\u002F\u002Ffonts.googleapis.com\u002Fcss2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');\r\n\r\n* {\r\n box-sizing: border-box;\r\n}\r\n\r\nbody {\r\n font-family: \"Poppins\", sans-serif;\r\n margin: 0;\r\n padding: 0;\r\n}\r\n\r\n.navbar {\r\n display: flex;\r\n position: relative;\r\n justify-content: space-around;\r\n align-items: center;\r\n border-bottom-color: rgb(234, 236, 243);\r\n border-bottom-style: solid;\r\n border-bottom-width: 1px;\r\n}\r\n\r\n.navbar img {\r\n width: 220px;\r\n}\r\n\r\n.navbar-links {\r\n height: 100%;\r\n}\r\n\r\n.navbar-links ul {\r\n display: flex;\r\n margin: 0;\r\n padding: 0;\r\n}\r\n\r\n.navbar-links li {\r\n list-style: none;\r\n}\r\n\r\n.navbar-links li a {\r\n display: block;\r\n text-decoration: none;\r\n padding: 1rem;\r\n color: #333;\r\n font-weight: 500;\r\n}\r\n\r\n.navbar-links li:hover {\r\n background-color: #DBDBDB;\r\n}\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"4485\" class=\"nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq pm pn po bk\" data-selectable-paragraph=\"\"\u003EAqui surge nosso primeiro problema: à medida que a tela fica menor, nossa navbar começa a transbordar horizontalmente. Esse comportamento não é desejável. Portanto, precisamos implementar o menu “hambúrguer”.\u003C\u002Fli\u003E\n\u003Cli id=\"9f60\" class=\"nw nx ho ny b nz pp ob oc od pq of og fk pr oi oj fn ps ol om fq pt oo op oq pm pn po bk\" data-selectable-paragraph=\"\"\u003EO primeiro passo para isso é adicionar no HTML o botão que corresponderá ao menu e as opções que ele oferecerá. Há diferentes maneiras de criamos esse botão, por ora, faremos ela na “mão”:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-html\"\u003E<!DOCTYPE html>\r\n<html lang=\"pt-br\">\r\n\r\n<head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>Menu Responsivo<\u002Ftitle>\r\n <link rel=\"stylesheet\" href=\"style.css\">\r\n<\u002Fhead>\r\n\r\n<body>\r\n <nav class=\"navbar\">\r\n <img src=\"logo.png\" alt=\"logo\">\r\n <a href=\"#\" class=\"toggle-button\">\r\n <span class=\"bar\"><\u002Fspan>\r\n <span class=\"bar\"><\u002Fspan>\r\n <span class=\"bar\"><\u002Fspan>\r\n <\u002Fa>\r\n <div class=\"navbar-links\">\r\n <ul>\r\n <li><a href=\"#\">Home<\u002Fa><\u002Fli>\r\n <li><a href=\"#\">Sobre<\u002Fa><\u002Fli>\r\n <li><a href=\"#\">Contato<\u002Fa><\u002Fli>\r\n <\u002Ful>\r\n <\u002Fdiv>\r\n <\u002Fnav>\r\n\r\n <script src=\"script.js\"><\u002Fscript>\r\n<\u002Fbody>\r\n\r\n<\u002Fhtml>\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp\u003EAgora vamos adicionar o CSS que vai construí-lo adequadamente na tela:\u003C\u002Fp\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-css\"\u003E.toggle-button {\r\n position: absolute;\r\n top: .75rem;\r\n right: 1rem;\r\n display: none;\r\n flex-direction: column;\r\n justify-content: space-between;\r\n width: 30px;\r\n height: 21px;\r\n}\r\n\r\n.toggle-button .bar {\r\n height: 3px;\r\n width: 100%;\r\n background-color: #333;\r\n border-radius: 10px;\r\n}\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"c2d6\" class=\"nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq pm pn po bk\" data-selectable-paragraph=\"\"\u003EAgora temos que ajustar para que ele apareça somente quando o dispositivo tiver a tela pequena. Para isso, precisaremos das Media Queries.\u003C\u002Fli\u003E\n\u003Cli id=\"7579\" class=\"nw nx ho ny b nz pp ob oc od pq of og fk pr oi oj fn ps ol om fq pt oo op oq pm pn po bk\" data-selectable-paragraph=\"\"\u003EAs media queries funcionam como condicionais dentro do nosso código CSS. Desta forma, conseguimos trabalhar com condições para que um elemento apareça ou não. Vamos ver como fica nosso exemplo:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-css\"\u003E@media (max-width: 800px) {\r\n .navbar {\r\n flex-direction: column;\r\n align-items: center;\r\n }\r\n\r\n .toggle-button {\r\n display: flex;\r\n }\r\n\r\n .navbar-links {\r\n display: none;\r\n width: 100%;\r\n }\r\n\r\n .navbar-links ul {\r\n width: 100%;\r\n flex-direction: column;\r\n }\r\n\r\n .navbar-links ul li {\r\n text-align: center;\r\n }\r\n\r\n .navbar-links ul li a {\r\n padding: .5rem 1rem;\r\n }\r\n\r\n}\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp\u003EAgora temos mais um problema para resolver. Ao clicar no menu, queremos que os itens apareçam e quando clicarmos novamente, que eles sumam. É neste momento que precisaremos da ajuda do JavaScript!\u003C\u002Fp\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-javascript\"\u003Econst toggleButton = document.getElementsByClassName(\"toggle-button\")[0];\r\nconst navbarLinks = document.getElementsByClassName(\"navbar-links\")[0];\r\n\r\ntoggleButton.addEventListener(\"click\", () => {\r\n navbarLinks.classList.toggle(\"active\");\r\n});\r\n\r\n.navbar-links.active {\r\n display: flex;\r\n}\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp id=\"f2c6\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EE pronto! Temos nossa navbar responsiva lindona! Basta adaptar os textos, opções, tamanhos e afins para melhor se adequar ao seu projeto! 😀\u003C\u002Fp\u003E\n\u003Cp id=\"03d4\" class=\"pw-post-body-paragraph nw nx ho ny b nz oa ob oc od oe of og fk oh oi oj fn ok ol om fq on oo op oq gp bk\" data-selectable-paragraph=\"\"\u003E—\u003C\u002Fp\u003E\n\u003Ch3 id=\"afc0\" class=\"pu ph ho bf pv pw px py fg pz qa qb fj qc qd qe qf qg qh qi qj qk ql qm qn qo bk\"\u003ERepositório\u003C\u002Fh3\u003E\n\u003Cp id=\"1648\" class=\"pw-post-body-paragraph nw nx ho ny b nz qp ob oc od qq of og fk qr oi oj fn qs ol om fq qt oo op oq gp bk\" data-selectable-paragraph=\"\"\u003E\u003Ca class=\"ag qu\" href=\"https:\u002F\u002Fgithub.com\u002FProfessor-DiegoPinho\u002Fmenu-responsivo\" target=\"_blank\" rel=\"noopener ugc nofollow noreferrer\"\u003Ehttps:\u002F\u002Fgithub.com\u002FProfessor-DiegoPinho\u002Fmenu-responsivo\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Ch3 id=\"f388\" class=\"pu ph ho bf pv pw px py fg pz qa qb fj qc qd qe qf qg qh qi qj qk ql qm qn qo bk\"\u003EAgradecimentos\u003C\u002Fh3\u003E\n\u003Cp id=\"932d\" class=\"pw-post-body-paragraph nw nx ho ny b nz qp ob oc od qq of og fk qr oi oj fn qs ol om fq qt oo op oq gp bk\" data-selectable-paragraph=\"\"\u003EGostou deste conteúdo? Então curta e compartilhe! 👏\u003C\u002Fp\u003E\n","excerpt":"\u003Cp\u003EExistem várias formas criativas e técnicas de lidar com responsividade (ex: Flexbox, Media Queries, CSS Grid)… Um claro exemplo é a navbar responsiva.\u003C\u002Fp\u003E\n","link":"https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fcomo-fazer-uma-navbar-responsiva","date":"11 jun, 2025","thumbnail":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F06\u002F26163321\u002FDesenvolvimento.jpg","externalMention":null,"author":{"id":144418,"thumbnail":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2018\u002F05\u002F30171243\u002Fdiego-pinho.jpg","name":"Diego Pinho","description":"Bacharel em Ciência da Computação pela PUCSP e MBA em Gestão da Tecnologia da Informação na FIAP. Autor do livro ECMAScript 6 - Entre de cabeça no futuro do JavaScript. Cofundador da Code Prestige e Community Manager no iMasters.","slug":"diegopinho","url":"https:\u002F\u002Fimasters.com.br\u002Fperfil\u002Fdiegopinho","registered":"2013-08-13 18:00:53","social":{"linkedin":null,"youtube":null,"facebook":"","twitter":"https:\u002F\u002Ftwitter.com\u002FDiegoPinho","instagram":null,"github":null,"url":"http:\u002F\u002Fwww.diegopinho.com.br","mail":"diego.pinho@imasters.com.br"},"articles_count":113,"views_count":1276900,"certifications":null,"conquests":null,"office":null},"categories":[{"title":"Desenvolvimento","slug":"desenvolvimento","id":7234,"link":"https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento"}],"tags":[{"title":"CSS","slug":"css","id":4250,"link":"https:\u002F\u002Fimasters.com.br\u002Fcss"},{"title":"desenvolvimento","slug":"desenvolvimento-2","id":186,"link":"https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento-2"},{"title":"desenvolvimento web","slug":"desenvolvimento-web","id":5269,"link":"https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento-web"},{"title":"html","slug":"html-2","id":405,"link":"https:\u002F\u002Fimasters.com.br\u002Fhtml-2"},{"title":"javascript","slug":"javascript-2","id":214,"link":"https:\u002F\u002Fimasters.com.br\u002Fjavascript-2"}],"seo":{"open_graph":{"title":"Dica de ouro: Saiba como fazer uma navbar responsiva","description":"Existem várias formas criativas e técnicas de lidar com responsividade (ex: Flexbox, Media Queries, CSS Grid)... Um claro exemplo é a navbar responsiva.","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":{"src":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F06\u002F26163321\u002FDesenvolvimento.jpg","width":800,"height":533},"modified_time":"2025-05-26T17:20:04-03:00","published_time":"2025-06-11T09:21:48-03:00"},"twitter":{"title":"Dica de ouro: Saiba como fazer uma navbar responsiva","description":"Existem várias formas criativas e técnicas de lidar com responsividade (ex: Flexbox, Media Queries, CSS Grid)... Um claro exemplo é a navbar responsiva.","type":"summary_large_image","image":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F06\u002F26163321\u002FDesenvolvimento.jpg"}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fcomo-fazer-uma-navbar-responsiva","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fcomo-fazer-uma-navbar-responsiva","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fcomo-fazer-uma-navbar-responsiva"},"type":"post"},{"id":163520,"title":"Popups nativos no navegador (Popover API) sem JavaScript!","content":"\u003Cp id=\"6acb\" class=\"pw-post-body-paragraph nv nw hn nx b ny nz oa ob oc od oe of fj og oh oi fm oj ok ol fp om on oo op go bj\" data-selectable-paragraph=\"\"\u003EPopups estão em toda parte. Eles são amplamente utilizados para diversos fins, como exibir anúncios, captar leads (através de formulários), fornecer notificações ou oferecer interações rápidas com o usuário.\u003C\u002Fp\u003E\n\u003Cp id=\"a40f\" class=\"pw-post-body-paragraph nv nw hn nx b ny nz oa ob oc od oe of fj og oh oi fm oj ok ol fp om on oo op go bj\" data-selectable-paragraph=\"\"\u003EEmbora possam ser úteis para chamar a atenção ou aumentar a conversão, seu uso excessivo ou intrusivo pode prejudicar a experiência do usuário, tornando importante o equilíbrio entre relevância e frequência.\u003C\u002Fp\u003E\n\u003Cp id=\"f6d8\" class=\"pw-post-body-paragraph nv nw hn nx b ny nz oa ob oc od oe of fj og oh oi fm oj ok ol fp om on oo op go bj\" data-selectable-paragraph=\"\"\u003EImplementar um popup não é nenhuma tarefa de outro mundo, mas também não é tão trivial quanto gostaríamos. É ncessário criar a interface com HTML, customizar sua aparência com CSS e lidar com os diferentes casos de interação com o JS.\u003C\u002Fp\u003E\n\u003Cp id=\"dd7b\" class=\"pw-post-body-paragraph nv nw hn nx b ny nz oa ob oc od oe of fj og oh oi fm oj ok ol fp om on oo op go bj\" data-selectable-paragraph=\"\"\u003EÉ por isso mesmo que geralmente usamos bibliotecas como o SweetAlert2 para fazer isso pra gente. Mas e se eu te disser que já existe uma API nativa para fazer isso? Estou falando da API popover! E sabe o melhor? Não precisamos nem de JavaScript! 😮\u003C\u002Fp\u003E\n\u003Cp id=\"d1ba\" class=\"pw-post-body-paragraph nv nw hn nx b ny nz oa ob oc od oe of fj og oh oi fm oj ok ol fp om on oo op go bj\" data-selectable-paragraph=\"\"\u003EPara exemplificar o seu funcionamento, nós faremos uma pequena janelinha para que o usuário se cadastre na nossa newsletter.\u003C\u002Fp\u003E\n\u003Cp id=\"b136\" class=\"pw-post-body-paragraph nv nw hn nx b ny nz oa ob oc od oe of fj og oh oi fm oj ok ol fp om on oo op go bj\" data-selectable-paragraph=\"\"\u003EA primeira coisa que precisaremos é de um botão que vai acionar a nossa caixinha:\u003C\u002Fp\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-html\"\u003E<!DOCTYPE html>\r\n<html lang=\"pt-br\">\r\n\r\n<head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>Popover API<\u002Ftitle>\r\n<\u002Fhead>\r\n\r\n<body>\r\n <button>\r\n Inscreva-se na nossa newsletter!\r\n <\u002Fbutton>\r\n<\u002Fbody>\r\n\r\n<\u002Fhtml>\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp data-selectable-paragraph=\"\"\u003EAgora vamos atrelar este comportamento com a janela que desejamos que apareça. Para isso, usamos o atributo \u003Cstrong class=\"nx ho\"\u003Epopovertarget\u003C\u002Fstrong\u003E. Veja:\u003C\u002Fp\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-html\"\u003E<!DOCTYPE html>\r\n<html lang=\"pt-br\">\r\n\r\n<head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>Popover API<\u002Ftitle>\r\n <style>\r\n #newsletter-box::backdrop {\r\n background: rgba(0, 0, 0, 0.6);\r\n }\r\n <\u002Fstyle>\r\n<\u002Fhead>\r\n\r\n<body>\r\n <button popovertarget=\"newsletter-box\">\r\n Inscreva-se na nossa newsletter!\r\n <\u002Fbutton>\r\n\r\n <div id=\"newsletter-box\" popover>\r\n O conteúdo fica aqui\r\n <\u002Fdiv>\r\n\r\n<\u002Fbody>\r\n\r\n<\u002Fhtml>\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp id=\"00da\" class=\"pw-post-body-paragraph nv nw hn nx b ny nz oa ob oc od oe of fj og oh oi fm oj ok ol fp om on oo op go bj\" data-selectable-paragraph=\"\"\u003EOlha só que legal o resultado!\u003C\u002Fp\u003E\n\u003Cfigure class=\"pr ps pt pu pv mx ng nh paragraph-image\"\u003E\n\u003Cdiv class=\"nq nr ed ns bg nt\" tabindex=\"0\" role=\"button\"\u003E\n\u003Cdiv class=\"ng nh qi\"\u003E\u003Cpicture\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002Fformat:webp\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002Fformat:webp\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002Fformat:webp\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002Fformat:webp\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002Fformat:webp\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002Fformat:webp\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1400\u002Fformat:webp\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 1400w\" type=\"image\u002Fwebp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \u002F\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1400\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \u002F\u003E\u003Cimg class=\"bg eq nu c\" role=\"presentation\" src=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:656\u002F1*f7P3E6KoZ2Hw9akS7X1I9g.gif\" alt=\"\" width=\"700\" height=\"511\" \u002F\u003E\u003C\u002Fpicture\u003E\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\n\u003C\u002Ffigure\u003E\n\u003Cp id=\"fcac\" class=\"pw-post-body-paragraph nv nw hn nx b ny nz oa ob oc od oe of fj og oh oi fm oj ok ol fp om on oo op go bj\" data-selectable-paragraph=\"\"\u003EMas e se não ficar claro para o usuário que ele deve clicar fora do modal ou usar a tecla \u003Ccode class=\"cw qj qk ql qa b\"\u003Eesc\u003C\u002Fcode\u003E para sair?\u003C\u002Fp\u003E\n\u003Cp id=\"550c\" class=\"pw-post-body-paragraph nv nw hn nx b ny nz oa ob oc od oe of fj og oh oi fm oj ok ol fp om on oo op go bj\" data-selectable-paragraph=\"\"\u003ENeste caso, podemos alterar o atributo \u003Ccode class=\"cw qj qk ql qa b\"\u003Epopover\u003C\u002Fcode\u003E do nosso modal para ser manual!\u003C\u002Fp\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-html\"\u003E<div id=\"newsletter-box\" popover=\"manual\">\r\n O conteúdo fica aqui\r\n<\u002Fdiv>\r\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp\u003ESó que agora está impossível sair do modal! Vamos adicionar um botão para acionar o comportamento de fechar.\u003C\u002Fp\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-html\"\u003E<div id=\"newsletter-box\" popover=\"manual\">\r\n <button class=\"close-btn\" popovertarget=\"newsletter-box\" popovertargetaction=\"hide\">\r\n <span aria-hidden=\"true\">❌<\u002Fspan>\r\n <\u002Fbutton>\r\n <p>O conteúdo fica aqui<\u002Fp>\r\n<\u002Fdiv>\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp id=\"7f44\" class=\"pw-post-body-paragraph nv nw hn nx b ny nz oa ob oc od oe of fj og oh oi fm oj ok ol fp om on oo op go bj\" data-selectable-paragraph=\"\"\u003EPronto! Inclusive agora podemos tirar o valor “manual” do atributo popover e ter os dois comportamentos!\u003C\u002Fp\u003E\n\u003Cp id=\"2da5\" class=\"pw-post-body-paragraph nv nw hn nx b ny nz oa ob oc od oe of fj og oh oi fm oj ok ol fp om on oo op go bj\" data-selectable-paragraph=\"\"\u003E—\u003C\u002Fp\u003E\n\u003Ch3 id=\"c425\" class=\"oq or hn be os ot ou ov ff ow ox oy fi oz pa pb pc pd pe pf pg ph pi pj pk pl bj\"\u003E\u003Cspan style=\"font-size: 18pt;\"\u003ERepositório\u003C\u002Fspan\u003E\u003C\u002Fh3\u003E\n\u003Cp id=\"3db0\" class=\"pw-post-body-paragraph nv nw hn nx b ny pm oa ob oc pn oe of fj po oh oi fm pp ok ol fp pq on oo op go bj\" data-selectable-paragraph=\"\"\u003E\u003Ca class=\"af qm\" href=\"https:\u002F\u002Fgithub.com\u002FProfessor-DiegoPinho\u002Fpopover-api\" target=\"_blank\" rel=\"noopener ugc nofollow noreferrer\"\u003Ehttps:\u002F\u002Fgithub.com\u002FProfessor-DiegoPinho\u002Fpopover-api\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp id=\"2da5\" class=\"pw-post-body-paragraph nv nw hn nx b ny nz oa ob oc od oe of fj og oh oi fm oj ok ol fp om on oo op go bj\" data-selectable-paragraph=\"\"\u003E—\u003C\u002Fp\u003E\n\u003Ch3 id=\"eea3\" class=\"oq or hn be os ot ou ov ff ow ox oy fi oz pa pb pc pd pe pf pg ph pi pj pk pl bj\"\u003E\u003Cspan style=\"font-size: 18pt;\"\u003EVersão em vídeo\u003C\u002Fspan\u003E\u003C\u002Fh3\u003E\n\u003Cp id=\"9a4b\" class=\"pw-post-body-paragraph nv nw hn nx b ny pm oa ob oc pn oe of fj po oh oi fm pp ok ol fp pq on oo op go bj\" data-selectable-paragraph=\"\"\u003EConfira a versão em vídeo desse artigo!\u003C\u002Fp\u003E\n\u003Cfigure class=\"pr ps pt pu pv mx\"\u003E\n\u003Cdiv class=\"pw er l ed\"\u003E\n\u003Cdiv class=\"px py l\"\u003E\u003Ciframe class=\"em n hd dy bg\" title=\"Popups nativos com a Popover API [HTML\u002FCSS]\" src=\"https:\u002F\u002Fcdn.embedly.com\u002Fwidgets\u002Fmedia.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fu7lvwQ1tryc%3Ffeature%3Doembed&display_name=YouTube&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Du7lvwQ1tryc&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2Fu7lvwQ1tryc%2Fhqdefault.jpg&type=text%2Fhtml&schema=youtube\" width=\"854\" height=\"480\" frameborder=\"0\" scrolling=\"no\" allowfullscreen=\"allowfullscreen\" data-mce-fragment=\"1\"\u003E\u003C\u002Fiframe\u003E\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\n\u003C\u002Ffigure\u003E\n\u003Cp id=\"7c64\" class=\"pw-post-body-paragraph nv nw hn nx b ny nz oa ob oc od oe of fj og oh oi fm oj ok ol fp om on oo op go bj\" data-selectable-paragraph=\"\"\u003E—\u003C\u002Fp\u003E\n","excerpt":"\u003Cp\u003EPopups estão em toda parte. Eles são amplamente utilizados para diversos fins, como exibir anúncios, captar leads (através de formulários), fornecer…\u003C\u002Fp\u003E\n","link":"https:\u002F\u002Fimasters.com.br\u002Fcss\u002Fpopups-nativos-no-navegador-popover-api-sem-javascript","date":"19 mai, 2025","thumbnail":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F15145637\u002FCSS.jpg","externalMention":null,"author":{"id":144418,"thumbnail":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2018\u002F05\u002F30171243\u002Fdiego-pinho.jpg","name":"Diego Pinho","description":"Bacharel em Ciência da Computação pela PUCSP e MBA em Gestão da Tecnologia da Informação na FIAP. Autor do livro ECMAScript 6 - Entre de cabeça no futuro do JavaScript. Cofundador da Code Prestige e Community Manager no iMasters.","slug":"diegopinho","url":"https:\u002F\u002Fimasters.com.br\u002Fperfil\u002Fdiegopinho","registered":"2013-08-13 18:00:53","social":{"linkedin":null,"youtube":null,"facebook":"","twitter":"https:\u002F\u002Ftwitter.com\u002FDiegoPinho","instagram":null,"github":null,"url":"http:\u002F\u002Fwww.diegopinho.com.br","mail":"diego.pinho@imasters.com.br"},"articles_count":113,"views_count":1276900,"certifications":null,"conquests":null,"office":null},"categories":[{"title":"CSS","slug":"css","id":7219,"link":"https:\u002F\u002Fimasters.com.br\u002Fcss"},{"title":"HTML","slug":"html","id":7221,"link":"https:\u002F\u002Fimasters.com.br\u002Fhtml"},{"title":"Tecnologia","slug":"tecnologia","id":4254,"link":"https:\u002F\u002Fimasters.com.br\u002Ftecnologia"},{"title":"Tendências","slug":"tendencias","id":7264,"link":"https:\u002F\u002Fimasters.com.br\u002Ftendencias"}],"tags":[{"title":"CSS","slug":"css","id":4250,"link":"https:\u002F\u002Fimasters.com.br\u002Fcss"},{"title":"html","slug":"html-2","id":405,"link":"https:\u002F\u002Fimasters.com.br\u002Fhtml-2"}],"seo":{"open_graph":{"title":"Popups nativos no navegador (Popover API) sem JavaScript!","description":"Popups estão em toda parte. Eles são amplamente utilizados para diversos fins, como exibir anúncios, captar leads (através de formulários), fornecer...","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":{"src":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F15145637\u002FCSS.jpg","width":800,"height":533},"modified_time":"2025-05-15T15:31:25-03:00","published_time":"2025-05-19T09:15:46-03:00"},"twitter":{"title":"Popups nativos no navegador (Popover API) sem JavaScript!","description":"Popups estão em toda parte. Eles são amplamente utilizados para diversos fins, como exibir anúncios, captar leads (através de formulários), fornecer...","type":"summary_large_image","image":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F15145637\u002FCSS.jpg"}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fcss\u002Fpopups-nativos-no-navegador-popover-api-sem-javascript","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fcss\u002Fpopups-nativos-no-navegador-popover-api-sem-javascript","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fcss\u002Fpopups-nativos-no-navegador-popover-api-sem-javascript"},"type":"post"},{"id":163359,"title":"Como enviar e-mails com o JavaScript usando o EmailJS","content":"\u003Cp id=\"d1ec\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003ETer um formulário de contato no seu site pessoal ou do seu negócio geralmente é uma boa ideia, afinal de contas, facilita muito o contato das pessoas com você.\u003C\u002Fp\u003E\n\u003Cp id=\"044f\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003EImplementar um formulário no HTML não é muito difícil, mas existe um problemão: \u003Cstrong class=\"nz hp\"\u003Ecomo vamos enviar um e-mail a partir daquele formulário?\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp id=\"fec4\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003ECaso você esteja usando um serviço de hospedagem como o Hostgator, Hostinger e afins, talvez você consiga utilizar o servidor PHP destas hospedagens para isso. Pode ser meio chato de configurar, mas funciona.\u003C\u002Fp\u003E\n\u003Cp id=\"7564\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003EMas quando isso não é possível, nós precisamos de um back-end.\u003C\u002Fp\u003E\n\u003Cp id=\"7f19\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003EE como eu sei que você não está afim de fazer um back-end para o seu site só pra isso (até porque você vai ter um outra dor de cabeça pra conseguir hospedar este outro serviço), hoje eu vou te mostrar como usar o \u003Ca class=\"ag os\" href=\"https:\u002F\u002Fwww.emailjs.com\u002F\" target=\"_blank\" rel=\"noopener ugc nofollow noreferrer\"\u003E\u003Cstrong class=\"nz hp\"\u003EEmailJS\u003C\u002Fstrong\u003E\u003C\u002Fa\u003E!\u003C\u002Fp\u003E\n\u003Ch2\u003EEmailJS\u003C\u002Fh2\u003E\n\u003Cp id=\"12ca\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003EEle vai facilitar bastante este processo.\u003C\u002Fp\u003E\n\u003Cp id=\"c44e\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003EComo a própria tela inicial do site já diz, a ideia do EmailJS é que você possa enviar um e-mail diretamente do seu código, sem a necessidade de um servidor. Pois bem, vamos ver então como isso funciona.\u003C\u002Fp\u003E\n\u003Cfigure class=\"pu pv pw px py mz ni nj paragraph-image\"\u003E\n\u003Cdiv class=\"ns nt ef nu bh nv\" tabindex=\"0\" role=\"button\"\u003E\n\u003Cdiv class=\"ni nj qh\"\u003E\u003Cpicture\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002Fformat:webp\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002Fformat:webp\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002Fformat:webp\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002Fformat:webp\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002Fformat:webp\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002Fformat:webp\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1400\u002Fformat:webp\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 1400w\" type=\"image\u002Fwebp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \u002F\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1400\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \u002F\u003E\u003Cimg class=\"bh es nw c\" role=\"presentation\" src=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1050\u002F1*_5UEbB5V6jnfZqYaibJBcQ.png\" alt=\"\" width=\"700\" height=\"438\" \u002F\u003E\u003C\u002Fpicture\u003E\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\u003Cfigcaption class=\"qc qd qe ni nj qf qg bf b bg z dz\" data-selectable-paragraph=\"\"\u003ETela inicial do EmailJS\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp id=\"779d\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003EPara entender como tudo funciona, vamos começar pela construção de um formulário simples \u003Cem class=\"qi\"\u003E(o código completo do repositório você encontra no final do artigo)\u003C\u002Fem\u003E:\u003C\u002Fp\u003E\n\u003Ch3 id=\"794c\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\"\u003E\u003Cspan style=\"font-size: 18pt;\"\u003E\u003Cstrong class=\"nz hp\"\u003Eindex.html\u003C\u002Fstrong\u003E\u003C\u002Fspan\u003E\u003C\u002Fh3\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-html\"\u003E<!DOCTYPE html>\r\n<html lang=\"pt-br\">\r\n\r\n<head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>Formulário<\u002Ftitle>\r\n <link rel=\"stylesheet\" href=\"style.css\">\r\n<\u002Fhead>\r\n\r\n<body>\r\n <form id=\"form\">\r\n <label for=\"nome\">Nome<\u002Flabel>\r\n <input type=\"text\" id=\"nome\" name=\"nome\" required>\r\n <br>\r\n <label for=\"email\">Email<\u002Flabel>\r\n <input type=\"email\" id=\"email\" name=\"email\" required>\r\n <br>\r\n <label for=\"mensagem\">Mensagem<\u002Flabel>\r\n <textarea id=\"mensagem\" name=\"mensagem\" required><\u002Ftextarea>\r\n <input type=\"submit\" value=\"Enviar\">\r\n <\u002Fform>\r\n\r\n <script src=\"script.js\"><\u002Fscript>\r\n<\u002Fbody>\r\n\r\n<\u002Fhtml>\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Ch3\u003E\u003Cspan style=\"font-size: 18pt;\"\u003E\u003Cstrong class=\"nz hp\"\u003Estyle.css\u003C\u002Fstrong\u003E\u003C\u002Fspan\u003E\u003C\u002Fh3\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-css\"\u003E@import url('https:\u002F\u002Ffonts.googleapis.com\u002Fcss2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap');\r\n\r\n* {\r\n box-sizing: border-box;\r\n}\r\n\r\nbody {\r\n font-family: \"Roboto\", serif;\r\n margin: 0;\r\n padding: 0;\r\n background-color: aliceblue;\r\n width: 100vw;\r\n height: 100vh;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n}\r\n\r\n#form {\r\n background-color: #fff;\r\n padding: 20px;\r\n border-radius: 8px;\r\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\r\n max-width: 400px;\r\n width: 100%;\r\n}\r\n\r\n#form label {\r\n display: block;\r\n margin-bottom: 5px;\r\n font-weight: bold;\r\n color: #333;\r\n}\r\n\r\n#form input[type=\"text\"],\r\n#form input[type=\"email\"],\r\n#form textarea {\r\n width: 100%;\r\n padding: 10px;\r\n margin-bottom: 15px;\r\n border: 1px solid #ddd;\r\n border-radius: 4px;\r\n font-size: 14px;\r\n box-sizing: border-box;\r\n}\r\n\r\n#form textarea {\r\n resize: vertical;\r\n min-height: 80px;\r\n}\r\n\r\n#form input[type=\"submit\"] {\r\n background-color: #007BFF;\r\n color: white;\r\n padding: 10px 15px;\r\n border: none;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-size: 16px;\r\n}\r\n\r\n#form input[type=\"submit\"]:hover {\r\n background-color: #0056b3;\r\n}\r\n\r\n#form input:focus,\r\n#form textarea:focus {\r\n border-color: #007BFF;\r\n outline: none;\r\n box-shadow: 0 0 4px rgba(0, 123, 255, 0.25);\r\n}\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Ch3\u003E\u003Cspan style=\"font-size: 18pt;\"\u003E\u003Cstrong class=\"nz hp\"\u003Escript.js\u003C\u002Fstrong\u003E\u003C\u002Fspan\u003E\u003C\u002Fh3\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-javascript\"\u003Econst form = document.querySelector('#form');\r\nform.addEventListener('submit', (e) => {\r\n e.preventDefault();\r\n console.log(\"passei aqui!\");\r\n});\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp data-selectable-paragraph=\"\"\u003EO primeiro passo para usar a ferramenta será inserir o código da biblioteca dentro do nosso projeto. Farei isso usando um CDN:\u003C\u002Fp\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-javascript\"\u003E<script type=\"text\u002Fjavascript\" src=\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002F@emailjs\u002Fbrowser@4\u002Fdist\u002Femail.min.js\"><\u002Fscript>\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp id=\"f23e\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003EAgora, antes de continuarmos o código, precisamos de uma \u003Cstrong class=\"nz hp\"\u003EAPI KEY\u003C\u002Fstrong\u003E. Essa chave você conseguirá apenas depois de criar sua conta e acessar a área de configurações no site. Será semelhante a esta aqui:\u003C\u002Fp\u003E\n\u003Cfigure class=\"pu pv pw px py mz ni nj paragraph-image\"\u003E\n\u003Cdiv class=\"ni nj qs\"\u003E\u003Cpicture\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002Fformat:webp\u002F1*oOHyswkp5zdlbulwONGFag.png 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002Fformat:webp\u002F1*oOHyswkp5zdlbulwONGFag.png 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002Fformat:webp\u002F1*oOHyswkp5zdlbulwONGFag.png 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002Fformat:webp\u002F1*oOHyswkp5zdlbulwONGFag.png 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002Fformat:webp\u002F1*oOHyswkp5zdlbulwONGFag.png 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002Fformat:webp\u002F1*oOHyswkp5zdlbulwONGFag.png 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1142\u002Fformat:webp\u002F1*oOHyswkp5zdlbulwONGFag.png 1142w\" type=\"image\u002Fwebp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 571px\" \u002F\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002F1*oOHyswkp5zdlbulwONGFag.png 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002F1*oOHyswkp5zdlbulwONGFag.png 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002F1*oOHyswkp5zdlbulwONGFag.png 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002F1*oOHyswkp5zdlbulwONGFag.png 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002F1*oOHyswkp5zdlbulwONGFag.png 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002F1*oOHyswkp5zdlbulwONGFag.png 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1142\u002F1*oOHyswkp5zdlbulwONGFag.png 1142w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 571px\" data-testid=\"og\" \u002F\u003E\u003Cimg class=\"bh es nw c\" role=\"presentation\" src=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:857\u002F1*oOHyswkp5zdlbulwONGFag.png\" alt=\"\" width=\"571\" height=\"446\" \u002F\u003E\u003C\u002Fpicture\u003E\u003C\u002Fdiv\u003E\u003Cfigcaption class=\"qc qd qe ni nj qf qg bf b bg z dz\" data-selectable-paragraph=\"\"\u003EChave pública de API utilizada atribuída ao usuário criado no EmailJS\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp id=\"dbc5\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003ECom essa chave em mãos, podemos voltar para o nosso \u003Cstrong class=\"nz hp\"\u003Escript.js\u003C\u002Fstrong\u003E e inicializar o serviço:\u003C\u002Fp\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-javascript\"\u003Eemailjs.init({\r\n publicKey: \"A CHAVE DE API AQUI\",\r\n});\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp id=\"d608\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003EAgora voltaremos pro painel do EmailJS porque precisamos configurar duas outras coisas fundamentais:\u003C\u002Fp\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"c50c\" class=\"nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or qt qu qv bk\" data-selectable-paragraph=\"\"\u003EUm e-mail de serviço (email service);\u003C\u002Fli\u003E\n\u003Cli id=\"379f\" class=\"nx ny ho nz b oa qw oc od oe qx og oh fl qy oj ok fo qz om on fr ra op oq or qt qu qv bk\" data-selectable-paragraph=\"\"\u003EUm template de e-mail (email template).\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp id=\"6387\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003EO serviço de e-mail será basicamente a configuração da sua conta de e-mail que será usada para o envio dos e-mails. Você consegue usar os principais serviços de e-mail do mercado (Gmail, iCloud, Outlook) ou configurar o próprio servidor SMTP.\u003C\u002Fp\u003E\n\u003Cfigure class=\"pu pv pw px py mz ni nj paragraph-image\"\u003E\n\u003Cdiv class=\"ni nj rb\"\u003E\u003Cpicture\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002Fformat:webp\u002F1*D_ZTDR4XconriYiO1-KTGw.png 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002Fformat:webp\u002F1*D_ZTDR4XconriYiO1-KTGw.png 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002Fformat:webp\u002F1*D_ZTDR4XconriYiO1-KTGw.png 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002Fformat:webp\u002F1*D_ZTDR4XconriYiO1-KTGw.png 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002Fformat:webp\u002F1*D_ZTDR4XconriYiO1-KTGw.png 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002Fformat:webp\u002F1*D_ZTDR4XconriYiO1-KTGw.png 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:868\u002Fformat:webp\u002F1*D_ZTDR4XconriYiO1-KTGw.png 868w\" type=\"image\u002Fwebp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 434px\" \u002F\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002F1*D_ZTDR4XconriYiO1-KTGw.png 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002F1*D_ZTDR4XconriYiO1-KTGw.png 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002F1*D_ZTDR4XconriYiO1-KTGw.png 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002F1*D_ZTDR4XconriYiO1-KTGw.png 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002F1*D_ZTDR4XconriYiO1-KTGw.png 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002F1*D_ZTDR4XconriYiO1-KTGw.png 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:868\u002F1*D_ZTDR4XconriYiO1-KTGw.png 868w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 434px\" data-testid=\"og\" \u002F\u003E\u003Cimg class=\"bh es nw c\" role=\"presentation\" src=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:651\u002F1*D_ZTDR4XconriYiO1-KTGw.png\" alt=\"\" width=\"434\" height=\"472\" \u002F\u003E\u003C\u002Fpicture\u003E\u003C\u002Fdiv\u003E\u003Cfigcaption class=\"qc qd qe ni nj qf qg bf b bg z dz\" data-selectable-paragraph=\"\"\u003EConfiguração de um serviço de e-mail na plataforma\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp id=\"8d45\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003EFeito isso, partiremos para o template de e-mail.\u003C\u002Fp\u003E\n\u003Cp id=\"27f7\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003EO importante neste template é que você use os campos dinâmicos os com os mesmos nomes que você está usando no seu formulário. Em nosso caso, temos: \u003Cstrong class=\"nz hp\"\u003Enome\u003C\u002Fstrong\u003E, \u003Cstrong class=\"nz hp\"\u003Eemail\u003C\u002Fstrong\u003E e \u003Cstrong class=\"nz hp\"\u003Emessage\u003C\u002Fstrong\u003E. por exemplo:\u003C\u002Fp\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-javascript\"\u003EMensagem enviada por: {{name}} <br \u002F>\r\nEmail: {{email}} <br \u002F>\r\nMensagem: {{message}}\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp data-selectable-paragraph=\"\"\u003ETanto o seu template quanto o seu serviço possuem identificadores únicos. Precisaremos deles. Agora sim podemos fechar o nosso arquivo JavaScript com o envio do e-mail:\u003C\u002Fp\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-javascript\"\u003Eemailjs.sendForm(ID_DO_SERVICO, ID_DO_TEMPLATE, e.target)\r\n .then((response) => { alert(\"Mensagem enviada com sucesso!\"); })\r\n .catch((error) => {\r\n console.log(error);\r\n alert(\"Ocorreu um erro com o envio do seu e-mail\");\r\n });\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp data-selectable-paragraph=\"\"\u003EO código inteiro ficará semelhante a este:\u003C\u002Fp\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-javascript\"\u003Econst form = document.querySelector('#form');\r\nform.addEventListener('submit', (e) => {\r\n e.preventDefault();\r\n\r\n emailjs.init({\r\n publicKey: \"hVsyIaGI0Az4LCK_M\",\r\n });\r\n\r\n emailjs.sendForm(\"ID_DO_SERVICO\", \"ID_DO_TEMPLATE\", form)\r\n .then((response) => alert(\"Mensagem enviada com sucesso!\"))\r\n .catch((error) => {\r\n console.log(error);\r\n alert(\"Erro ao enviar mensagem!\")\r\n });\r\n});\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp id=\"17b4\" class=\"pw-post-body-paragraph nx ny ho nz b oa ob oc od oe of og oh fl oi oj ok fo ol om on fr oo op oq or gp bk\" data-selectable-paragraph=\"\"\u003EE está pronto! Agora é só esperar o contato da galera 🙂\u003C\u002Fp\u003E\n\u003Ch3 id=\"e0a2\" class=\"ot ou ho bf ov ow ox oy fh oz pa pb fk pc pd pe pf pg ph pi pj pk pl pm pn po bk\"\u003E\u003Cspan style=\"font-size: 18pt;\"\u003ERepositório\u003C\u002Fspan\u003E\u003C\u002Fh3\u003E\n\u003Cp id=\"fe29\" class=\"pw-post-body-paragraph nx ny ho nz b oa pp oc od oe pq og oh fl pr oj ok fo ps om on fr pt op oq or gp bk\" data-selectable-paragraph=\"\"\u003E\u003Ca class=\"ag os\" href=\"https:\u002F\u002Fgithub.com\u002FProfessor-DiegoPinho\u002Femail-com-emailjs\" target=\"_blank\" rel=\"noopener ugc nofollow noreferrer\"\u003Ehttps:\u002F\u002Fgithub.com\u002FProfessor-DiegoPinho\u002Femail-com-emailjs\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Ch3 id=\"1d84\" class=\"ot ou ho bf ov ow ox oy fh oz pa pb fk pc pd pe pf pg ph pi pj pk pl pm pn po bk\"\u003E\u003Cspan style=\"font-size: 18pt;\"\u003EVersão em vídeo\u003C\u002Fspan\u003E\u003C\u002Fh3\u003E\n\u003Cp id=\"bc46\" class=\"pw-post-body-paragraph nx ny ho nz b oa pp oc od oe pq og oh fl pr oj ok fo ps om on fr pt op oq or gp bk\" data-selectable-paragraph=\"\"\u003EConfira a versão em vídeo desse artigo!\u003C\u002Fp\u003E\n\u003Cfigure class=\"pu pv pw px py mz\"\u003E\n\u003Cdiv class=\"pz et l ef\"\u003E\n\u003Cdiv class=\"qa qb l\"\u003E\u003Ciframe class=\"ep n he eb bh\" title=\"Como enviar e-mails com JavaScript\" src=\"https:\u002F\u002Fcdn.embedly.com\u002Fwidgets\u002Fmedia.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FQMTvjsd-oEg%3Ffeature%3Doembed&display_name=YouTube&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DQMTvjsd-oEg&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FQMTvjsd-oEg%2Fhqdefault.jpg&type=text%2Fhtml&schema=youtube\" width=\"854\" height=\"480\" frameborder=\"0\" scrolling=\"no\" allowfullscreen=\"allowfullscreen\" data-mce-fragment=\"1\"\u003E\u003C\u002Fiframe\u003E\u003C\u002Fdiv\u003E\n\u003Cdiv\u003E\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\u003Cfigcaption class=\"qc qd qe ni nj qf qg bf b bg z dz\"\u003E\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n","excerpt":"\u003Cp\u003EComo enviar e-mails com o JavaScript usando o EmailJS. Ter um formulário de contato no seu site pessoal ou do seu negócio geralmente é uma boa ideia, afinal\u003C\u002Fp\u003E\n","link":"https:\u002F\u002Fimasters.com.br\u002Fjavascript\u002Fcomo-enviar-e-mails-com-o-javascript-usando-o-emailjs","date":"16 abr, 2025","thumbnail":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F04\u002F29163133\u002Fjavascript1.jpg","externalMention":null,"author":{"id":144418,"thumbnail":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2018\u002F05\u002F30171243\u002Fdiego-pinho.jpg","name":"Diego Pinho","description":"Bacharel em Ciência da Computação pela PUCSP e MBA em Gestão da Tecnologia da Informação na FIAP. Autor do livro ECMAScript 6 - Entre de cabeça no futuro do JavaScript. Cofundador da Code Prestige e Community Manager no iMasters.","slug":"diegopinho","url":"https:\u002F\u002Fimasters.com.br\u002Fperfil\u002Fdiegopinho","registered":"2013-08-13 18:00:53","social":{"linkedin":null,"youtube":null,"facebook":"","twitter":"https:\u002F\u002Ftwitter.com\u002FDiegoPinho","instagram":null,"github":null,"url":"http:\u002F\u002Fwww.diegopinho.com.br","mail":"diego.pinho@imasters.com.br"},"articles_count":113,"views_count":1276900,"certifications":null,"conquests":null,"office":null},"categories":[{"title":"JavaScript","slug":"javascript","id":7220,"link":"https:\u002F\u002Fimasters.com.br\u002Fjavascript"}],"tags":[{"title":"EmailJS","slug":"emailjs","id":9217,"link":"https:\u002F\u002Fimasters.com.br\u002Femailjs"},{"title":"javascript","slug":"javascript-2","id":214,"link":"https:\u002F\u002Fimasters.com.br\u002Fjavascript-2"},{"title":"js","slug":"js","id":3311,"link":"https:\u002F\u002Fimasters.com.br\u002Fjs"}],"seo":{"open_graph":{"title":"Como enviar e-mails com o JavaScript usando o EmailJS","description":"Como enviar e-mails com o JavaScript usando o EmailJS. Ter um formulário de contato no seu site pessoal ou do seu negócio geralmente é uma boa ideia, afinal","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":{"src":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F04\u002F29163133\u002Fjavascript1.jpg","width":800,"height":533},"modified_time":"2025-04-29T16:32:41-03:00","published_time":"2025-04-16T14:05:46-03:00"},"twitter":{"title":"Como enviar e-mails com o JavaScript usando o EmailJS","description":"Como enviar e-mails com o JavaScript usando o EmailJS. Ter um formulário de contato no seu site pessoal ou do seu negócio geralmente é uma boa ideia, afinal","type":"summary_large_image","image":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F04\u002F29163133\u002Fjavascript1.jpg"}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fjavascript\u002Fcomo-enviar-e-mails-com-o-javascript-usando-o-emailjs","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fjavascript\u002Fcomo-enviar-e-mails-com-o-javascript-usando-o-emailjs","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fjavascript\u002Fcomo-enviar-e-mails-com-o-javascript-usando-o-emailjs"},"type":"post"},{"id":163032,"title":"Como usar Faker.js para gerar dados falsos (mas realistas) em JavaScript","content":"\u003Cp\u003ENo desenvolvimento de software, testar funcionalidades com dados reais nem sempre é a melhor opção. Seja para preservar a privacidade de informações sensíveis ou para simular cenários diversos, a geração de dados falsos é uma excelente alternativa. É aí que entra o \u003Ca class=\"af ov\" href=\"https:\u002F\u002Ffakerjs.dev\u002F\" target=\"_blank\" rel=\"noopener ugc nofollow noreferrer\"\u003E\u003Cstrong class=\"mo fr\"\u003EFaker.js\u003C\u002Fstrong\u003E\u003C\u002Fa\u003E, uma poderosa biblioteca para gerar dados fictícios de maneira rápida e eficiente.\u003C\u002Fp\u003E\n\u003Cdiv class=\"ab cb\"\u003E\n\u003Cdiv class=\"ci bh ev ew ex ey\"\u003E\n\u003Cp id=\"6512\" class=\"pw-post-body-paragraph mm mn fq mo b mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh ni nj fj bk\" data-selectable-paragraph=\"\"\u003EO \u003Cstrong class=\"mo fr\"\u003EFaker.js\u003C\u002Fstrong\u003E é uma biblioteca de código aberto que permite gerar dados falsos para diversos fins, como testes, protótipos e desenvolvimento de software. Com ele, você pode criar:\u003C\u002Fp\u003E\n\u003Cul class=\"\"\u003E\n\u003Cli id=\"0d8b\" class=\"mm mn fq mo b mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh ni nj pa pb pc bk\" data-selectable-paragraph=\"\"\u003ENomes e sobrenomes;\u003C\u002Fli\u003E\n\u003Cli id=\"6fbd\" class=\"mm mn fq mo b mp pd mr ms mt pe mv mw mx pf mz na nb pg nd ne nf ph nh ni nj pa pb pc bk\" data-selectable-paragraph=\"\"\u003EEndereços completos (ruas, cidades, estados e até CEPs;.\u003C\u002Fli\u003E\n\u003Cli id=\"57db\" class=\"mm mn fq mo b mp pd mr ms mt pe mv mw mx pf mz na nb pg nd ne nf ph nh ni nj pa pb pc bk\" data-selectable-paragraph=\"\"\u003EE-mails, números de telefone e até mesmo textos aleatórios para preencher campos de formulário.\u003C\u002Fli\u003E\n\u003Cli id=\"8d4d\" class=\"mm mn fq mo b mp pd mr ms mt pe mv mw mx pf mz na nb pg nd ne nf ph nh ni nj pa pb pc bk\" data-selectable-paragraph=\"\"\u003EEtc.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp id=\"3c62\" class=\"pw-post-body-paragraph mm mn fq mo b mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh ni nj fj bk\" data-selectable-paragraph=\"\"\u003EAlém disso, o Faker.js suporta diversos idiomas, incluindo o português do Brasil, o que torna os dados gerados ainda mais contextualizados e realistas.\u003C\u002Fp\u003E\n\u003Cp id=\"1257\" class=\"pw-post-body-paragraph mm mn fq mo b mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh ni nj fj bk\" data-selectable-paragraph=\"\"\u003EA melhor forma de entender todas as suas possibilidades é visitando a sua documentação. Lá, encontramos uma infinidade de categorias que vão desde pessoas, até números, locais, internet, e assim por diante.\u003C\u002Fp\u003E\n\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\n\u003Cdiv class=\"ln\"\u003E\n\u003Cdiv class=\"ab cb\"\u003E\n\u003Cdiv class=\"lo lp lq lr ls lt cf lu cg lv ci bh\"\u003E\n\u003Cfigure class=\"on oo op oq or ln me mf paragraph-image\"\u003E\n\u003Cdiv class=\"mg mh ed mi bh mj\" tabindex=\"0\" role=\"button\"\u003E\n\u003Cdiv class=\"lw lx aki\"\u003E\u003Cpicture\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002Fformat:webp\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002Fformat:webp\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002Fformat:webp\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002Fformat:webp\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002Fformat:webp\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002Fformat:webp\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:2000\u002Fformat:webp\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 2000w\" type=\"image\u002Fwebp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 1000px\" \u002F\u003E\u003Csource srcset=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:640\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 640w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:720\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 720w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:750\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 750w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:786\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 786w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:828\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 828w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1100\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 1100w, https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:2000\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png 2000w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 1000px\" data-testid=\"og\" \u002F\u003E\u003Cimg class=\"bh mk ml c\" role=\"presentation\" src=\"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1000\u002F1*d0lduGgrDc1cP3vyL7UKDQ.png\" alt=\"\" width=\"1000\" height=\"673\" \u002F\u003E\u003C\u002Fpicture\u003E\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\u003Cfigcaption class=\"akj rr akk lw lx akl akm bf b bg z dx\" data-selectable-paragraph=\"\"\u003EDocumentação da biblioteca Faker.js\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\n\u003Cdiv class=\"ab cb\"\u003E\n\u003Cdiv class=\"ci bh ev ew ex ey\"\u003E\n\u003Cp id=\"29ed\" class=\"pw-post-body-paragraph mm mn fq mo b mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh ni nj fj bk\" data-selectable-paragraph=\"\"\u003EO primeiro passo para usá-lo é instalá-lo. Podemos fazer isso facilmente com o comando:\u003C\u002Fp\u003E\n\u003Cpre class=\"on oo op oq or akn oz ako bp akp bb bk\"\u003E\u003Ccode\u003E\u003Cspan id=\"fecc\" class=\"akq nl fq oz b bg akr aks l akt aku\" data-selectable-paragraph=\"\"\u003Enpm install @faker-js\u002Ffaker\u003C\u002Fspan\u003E\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp id=\"6410\" class=\"pw-post-body-paragraph mm mn fq mo b mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh ni nj fj bk\" data-selectable-paragraph=\"\"\u003ENo arquivo em que você deseja usar o faker, faça o seguinte import:\u003C\u002Fp\u003E\n\u003Cpre class=\"on oo op oq or akn oz ako bp akp bb bk\"\u003E\u003Ccode\u003E\u003Cspan id=\"4896\" class=\"akq nl fq oz b bg akr aks l akt aku\" data-selectable-paragraph=\"\"\u003E\u003Cspan class=\"hljs-keyword\"\u003Eimport\u003C\u002Fspan\u003E { faker } \u003Cspan class=\"hljs-keyword\"\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\"hljs-string\"\u003E\"@faker-js\u002Ffaker\"\u003C\u002Fspan\u003E;\u003C\u002Fspan\u003E\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cp id=\"5657\" class=\"pw-post-body-paragraph mm mn fq mo b mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh ni nj fj bk\" data-selectable-paragraph=\"\"\u003EE pronto! Já conseguimos fazer uso das diversas possibilidades que a API nos oferece, como por exemplo, construir os dados de uma pessoa:\u003C\u002Fp\u003E\n\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\n\u003Cpre\u003E\u003Ccode class=\"line-numbers language-javascript\"\u003Eimport { faker } from \"@faker-js\u002Ffaker\";\r\n\r\nconst person = {\r\n firstName: faker.person.firstName(),\r\n lastName: faker.person.lastName(),\r\n email: faker.internet.email(),\r\n phone: faker.phone.number(),\r\n address: faker.location.streetAddress()\r\n}\r\n\r\nconsole.log(person);\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cdiv class=\"ab cb\"\u003E\n\u003Cdiv class=\"ci bh ev ew ex ey\"\u003E\n\u003Cpre class=\"on oo op oq or akn oz ako bp akp bb bk\"\u003E\u003Cspan id=\"3efb\" class=\"akq nl fq oz b bg akr aks l akt aku\" data-selectable-paragraph=\"\"\u003E\r\n\u003C\u002Fspan\u003EToda vez que rodamos este código, obtemos informações completamente diferentes!\u003C\u002Fpre\u003E\n\u003Ch3 id=\"34a6\" class=\"nk nl fq bf nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh bk\"\u003EVersão em vídeo\u003C\u002Fh3\u003E\n\u003Cp id=\"11e3\" class=\"pw-post-body-paragraph mm mn fq mo b mp oi mr ms mt oj mv mw mx ok mz na nb ol nd ne nf om nh ni nj fj bk\" data-selectable-paragraph=\"\"\u003EConfira a versão em vídeo desse artigo!\u003C\u002Fp\u003E\n\u003Cfigure class=\"on oo op oq or ln\"\u003E\n\u003Cdiv class=\"os ia l ed\"\u003E\n\u003Cdiv class=\"ot ou l\"\u003E\u003Ciframe class=\"em n fe dz bh\" title=\"Como usar o Faker.js para gerar dados falsos (mas realistas) em JavaScript\" src=\"https:\u002F\u002Fcdn.embedly.com\u002Fwidgets\u002Fmedia.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FBKE9pfIdPbI%3Ffeature%3Doembed&display_name=YouTube&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DBKE9pfIdPbI&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FBKE9pfIdPbI%2Fhqdefault.jpg&type=text%2Fhtml&schema=youtube\" width=\"854\" height=\"480\" frameborder=\"0\" scrolling=\"no\" allowfullscreen=\"allowfullscreen\" data-mce-fragment=\"1\"\u003E\u003C\u002Fiframe\u003E\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\n\u003C\u002Ffigure\u003E\n\u003Cp id=\"6512\" class=\"pw-post-body-paragraph mm mn fq mo b mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh ni nj fj bk\" data-selectable-paragraph=\"\"\u003E\n\u003C\u002Fdiv\u003E\n\u003C\u002Fdiv\u003E\n","excerpt":"\u003Cp\u003ENo desenvolvimento de software, testar… É aí que entra o Faker.js, uma poderosa biblioteca para gerar dados fictícios de maneira rápida e eficiente.\u003C\u002Fp\u003E\n","link":"https:\u002F\u002Fimasters.com.br\u002Fjavascript\u002Fcomo-usar-faker-js-para-gerar-dados-falsos-mas-realistas-em-javascript","date":"11 mar, 2025","thumbnail":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F25130509\u002FJavaScript-3.jpg","externalMention":null,"author":{"id":144418,"thumbnail":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2018\u002F05\u002F30171243\u002Fdiego-pinho.jpg","name":"Diego Pinho","description":"Bacharel em Ciência da Computação pela PUCSP e MBA em Gestão da Tecnologia da Informação na FIAP. Autor do livro ECMAScript 6 - Entre de cabeça no futuro do JavaScript. Cofundador da Code Prestige e Community Manager no iMasters.","slug":"diegopinho","url":"https:\u002F\u002Fimasters.com.br\u002Fperfil\u002Fdiegopinho","registered":"2013-08-13 18:00:53","social":{"linkedin":null,"youtube":null,"facebook":"","twitter":"https:\u002F\u002Ftwitter.com\u002FDiegoPinho","instagram":null,"github":null,"url":"http:\u002F\u002Fwww.diegopinho.com.br","mail":"diego.pinho@imasters.com.br"},"articles_count":113,"views_count":1276900,"certifications":null,"conquests":null,"office":null},"categories":[{"title":"JavaScript","slug":"javascript","id":7220,"link":"https:\u002F\u002Fimasters.com.br\u002Fjavascript"}],"tags":[{"title":"dados falsos","slug":"dados-falsos","id":9191,"link":"https:\u002F\u002Fimasters.com.br\u002Fdados-falsos"},{"title":"Faker","slug":"faker","id":6659,"link":"https:\u002F\u002Fimasters.com.br\u002Ffaker"},{"title":"javascript","slug":"javascript-2","id":214,"link":"https:\u002F\u002Fimasters.com.br\u002Fjavascript-2"}],"seo":{"open_graph":{"title":"Como usar Faker.js para gerar dados falsos (mas realistas) em JavaScript","description":"No desenvolvimento de software, testar... É aí que entra o Faker.js, uma poderosa biblioteca para gerar dados fictícios de maneira rápida e eficiente.","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":{"src":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F25130509\u002FJavaScript-3.jpg","width":800,"height":533},"modified_time":"2025-03-21T11:38:45-03:00","published_time":"2025-03-11T09:15:10-03:00"},"twitter":{"title":"Como usar Faker.js para gerar dados falsos (mas realistas) em JavaScript","description":"No desenvolvimento de software, testar... É aí que entra o Faker.js, uma poderosa biblioteca para gerar dados fictícios de maneira rápida e eficiente.","type":"summary_large_image","image":"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F25130509\u002FJavaScript-3.jpg"}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fjavascript\u002Fcomo-usar-faker-js-para-gerar-dados-falsos-mas-realistas-em-javascript","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fjavascript\u002Fcomo-usar-faker-js-para-gerar-dados-falsos-mas-realistas-em-javascript","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fjavascript\u002Fcomo-usar-faker-js-para-gerar-dados-falsos-mas-realistas-em-javascript"},"type":"post"}]},"categories":[{"title":"Desenvolvimento","slug":"desenvolvimento","id":7234,"link":"https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento"}],"tags":[{"title":"educação","slug":"educacao","id":2299,"link":"https:\u002F\u002Fimasters.com.br\u002Feducacao"},{"title":"games","slug":"games-2","id":2795,"link":"https:\u002F\u002Fimasters.com.br\u002Fgames-2"},{"title":"Jogos","slug":"jogos","id":846,"link":"https:\u002F\u002Fimasters.com.br\u002Fjogos"},{"title":"Twine","slug":"twine","id":7986,"link":"https:\u002F\u002Fimasters.com.br\u002Ftwine"}],"seo":{"open_graph":{"title":"Criando um jogo baseado em texto com o Twine - iMasters - We are Developers","description":"Neste artigo, o autor fala sobre ensinar crianças a programar e para essa tarefa, apresenta um passo a passo mostrando a criação de um jogo baseado em texto.","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":false,"modified_time":"2018-11-13T16:49:47-03:00","published_time":"2018-11-19T09:00:27-03:00"},"twitter":{"title":"Criando um jogo baseado em texto com o Twine - iMasters - We are Developers","description":"Neste artigo, o autor fala sobre ensinar crianças a programar e para essa tarefa, apresenta um passo a passo mostrando a criação de um jogo baseado em texto.","type":"summary_large_image","image":false}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fcriando-um-jogo-baseado-em-texto-com-o-twine","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fcriando-um-jogo-baseado-em-texto-com-o-twine","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fcriando-um-jogo-baseado-em-texto-com-o-twine"},"type":"post","articleViews":100}},"author":{"success":false,"isFetchingPagination":false,"maxPages":0,"page":1,"data":{}},"category":{"success":false,"data":{}},"categoryArticles":{"success":false,"isFetchingPagination":false,"maxPages":0,"page":1,"data":{}},"categoryMostRead":{"success":false,"data":{}},"home":{"success":false,"featured":[],"options":{"homeProducts":[]},"allCategories":{},"featuredArticles":{},"magazines":{"data":[]},"tv":{},"forums":[],"authorsRanking":{},"events":{},"certificatedUsers":[],"news":[]},"page":{"success":false,"data":{}},"magazine":{"success":false,"magazines":[]},"schedule":{"success":false,"data":{}},"searchResult":{"success":false,"totalPosts":0,"totalPage":0,"currentPage":1,"posts":[],"term":"","orderBy":"recents","currentFilter":"articles","isLoading":true,"isLoadingPagination":false},"singleNews":{"success":false,"data":{}},"listNews":{"success":false,"isFetchingPagination":false,"maxPages":0,"page":1,"data":[]},"sponsors":{"success":true,"data":[]},"header":{"success":true,"menus":{"main":[{"ID":138755,"order":1,"parent":0,"title":"Back-End","url":"https:\u002F\u002Fimasters.com.br\u002Fback-end","attr":"package","target":"","classes":"package","xfn":"","description":"Tecnologias utilizadas no backend da aplicação","object_id":7158,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]},{"ID":138756,"order":2,"parent":0,"title":"Mobile","url":"https:\u002F\u002Fimasters.com.br\u002Fmobile","attr":"package","target":"","classes":"package","xfn":"","description":"Conteúdos sobre Desenvolvimento Mobile nas plataformas iOS (iPhone e iPad) e Android.","object_id":4255,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]},{"ID":139476,"order":3,"parent":0,"title":"Front End","url":"https:\u002F\u002Fimasters.com.br\u002Ffront-end","attr":"package","target":"","classes":"package","xfn":"","description":"Conteúdos sobre HTML5, CSS3, Javascript, JQuery, Web Standards e SEO.","object_id":7304,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]},{"ID":138764,"order":4,"parent":0,"title":"DevSecOps","url":"https:\u002F\u002Fimasters.com.br\u002Fdevsecops","attr":"package","target":"","classes":"package","xfn":"","description":"","object_id":1,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]},{"ID":139204,"order":5,"parent":0,"title":"Design & UX","url":"https:\u002F\u002Fimasters.com.br\u002Fdesign-ux","attr":"package","target":"","classes":"package","xfn":"","description":"Conteúdos sobre User Experience, Arquitetura de Informação, Usabilidade, Acessibilidade, Design Responsivo, Teoria do Design e Photoshop.","object_id":7252,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]},{"ID":138759,"order":6,"parent":0,"title":"Data","url":"https:\u002F\u002Fimasters.com.br\u002Fdata","attr":"package","target":"","classes":"package","xfn":"","description":"Conteúdos sobre Banco de Dados Oracle, MySQL, SQL Server, MongoDB, DB2 e Postgre SQL, sobre BI e análise de dados.","object_id":16,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]},{"ID":138758,"order":7,"parent":0,"title":"APIs e Microsserviços","url":"https:\u002F\u002Fimasters.com.br\u002Fapis-microsservicos","attr":"package","target":"","classes":"package","xfn":"","description":"Dicas e tutoriais sobre APIs públicas como Facebook, Twitter, PayPal, Buscapé, Google, etc e arquitetura de microsserviços, com códigos de exemplo, vídeos, cursos.","object_id":4257,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]}],"secondary":[{"ID":138752,"order":1,"parent":0,"title":"Fórum iMasters","url":"https:\u002F\u002Fforum.imasters.com.br\u002F","attr":"","target":"_blank","classes":"","xfn":"","description":"","object_id":138752,"object":"custom","type":"custom","type_label":"Link personalizado","children":[]},{"ID":139067,"order":2,"parent":0,"title":"Portal E-Commerce Brasil","url":"http:\u002F\u002Fwww.ecommercebrasil.com.br","attr":"","target":"","classes":"","xfn":"","description":"","object_id":139067,"object":"custom","type":"custom","type_label":"Link personalizado","children":[]},{"ID":156289,"order":3,"parent":0,"title":"iMasters Business","url":"http:\u002F\u002Fbusiness.imasters.com.br","attr":"","target":"","classes":"","xfn":"","description":"","object_id":156289,"object":"custom","type":"custom","type_label":"Link personalizado","children":[]}]}},"webinar":{"success":false,"data":{}},"webinars":{"success":false,"isFetchingPagination":false,"maxPages":0,"page":1,"data":{"next":[],"prev":[]}},"tv":{"sectionNameLeft":{"small":"Vídeos","large":"iMasters TV"},"itemsLeft":[{"text":"Em Destaque","slug":"recents"},{"text":"Mais Vistos","slug":"most-viewed"}],"sectionNameRight":{"small":"","large":""},"itemsRight":[{"text":"Mais Recentes","slug":"recents"},{"text":"7Masters","slug":"7-masters"},{"text":"PHP Experience","slug":"php-experience"},{"text":"Android DevConference","slug":"android-devconference"},{"text":"Busca","slug":"search"}],"currentVideo":"recents","currentListVideo":"recents"}} window.__SERVER_VARS__ = {"applicationRestUrl":"https:\u002F\u002Fadmin.imasters.com.br\u002Fwp-json","applicationBaseUrl":"https:\u002F\u002Fadmin.imasters.com.br"}