{"id":14768,"date":"2023-08-28T18:20:02","date_gmt":"2023-08-29T01:20:02","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=14768"},"modified":"2023-08-31T11:21:04","modified_gmt":"2023-08-31T18:21:04","slug":"building-a-survey-app-with-netlify-and-couchbase","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/building-a-survey-app-with-netlify-and-couchbase\/","title":{"rendered":"Crie um aplicativo de pesquisa com Netlify e Couchbase"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">A equipe do Couchbase DevRel tem trabalhado com o <\/span><a href=\"https:\/\/badwebsite.club\/\"><span style=\"font-weight: 400;\">Clube do site ruim<\/span><\/a><span style=\"font-weight: 400;\"> em <\/span><a href=\"https:\/\/www.freecodecamp.org\/\"><span style=\"font-weight: 400;\">freeCodeCamp <\/span><\/a><span style=\"font-weight: 400;\">materiais.\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">O freeCodeCamp \u00e9 uma organiza\u00e7\u00e3o sem fins lucrativos que consiste em uma plataforma interativa de aprendizado na Web, um f\u00f3rum de comunidade on-line, salas de bate-papo, publica\u00e7\u00f5es on-line e organiza\u00e7\u00f5es locais que pretendem tornar o aprendizado de desenvolvimento de software acess\u00edvel a qualquer pessoa.<\/span><\/i><\/p>\n<p><i><span style=\"font-weight: 400;\">O Bad Website Club \u00e9 uma comunidade on-line que ajuda novos alunos em sua jornada de programa\u00e7\u00e3o.<\/span><\/i><\/p>\n<p><span style=\"font-weight: 400;\">Fizemos um streaming para mostrar aos alunos de fCC o que poderia acontecer com seus projetos em condi\u00e7\u00f5es mais \"reais\". Come\u00e7amos com o curso Responsive Web Design, pegamos alguns exemplos, como o formul\u00e1rio Survey (Pesquisa), os completamos e os colocamos em produ\u00e7\u00e3o. Toda a s\u00e9rie foi transmitida no YouTube, LinkedIn, Twitter e Twitch, e as grava\u00e7\u00f5es est\u00e3o dispon\u00edveis nesta lista de reprodu\u00e7\u00e3o do YouTube, se voc\u00ea quiser conferir: <\/span><a href=\"https:\/\/www.youtube.com\/watch?v=OkO1ZHH1N54&amp;list=PLcspbWiU9RutKoHwXID713a_GcTgeT6j6\"><span style=\"font-weight: 400;\" data-rich-links=\"{&quot;fple-t&quot;:&quot;New Couchbase Streams: Starting July 31st!&quot;,&quot;fple-u&quot;:&quot;https:\/\/www.youtube.com\/watch?v=OkO1ZHH1N54&amp;list=PLcspbWiU9RutKoHwXID713a_GcTgeT6j6&quot;,&quot;fple-mt&quot;:null,&quot;type&quot;:&quot;first-party-link&quot;}\">Novos fluxos do Couchbase: A partir de 31 de julho!<\/span><\/a><\/p>\n<p><iframe loading=\"lazy\" title=\"Novos fluxos do Couchbase: A partir de 31 de julho!\" width=\"900\" height=\"506\" src=\"https:\/\/www.youtube.com\/embed\/OkO1ZHH1N54?list=PLcspbWiU9RutKoHwXID713a_GcTgeT6j6\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe><\/p>\n<p><span style=\"font-weight: 400;\">Eu estava transmitindo pessoalmente no <\/span><a href=\"https:\/\/www.freecodecamp.org\/learn\/2022\/responsive-web-design\/build-a-survey-form-project\/build-a-survey-form\"><span style=\"font-weight: 400;\">Projeto de pesquisa<\/span><\/a><span style=\"font-weight: 400;\">. Nesta s\u00e9rie de publica\u00e7\u00f5es do blog, mostrarei todas as etapas adicionais que voc\u00ea pode fazer: publicar o c\u00f3digo no GitHub, implantar o Survey on-line com o Netlify e armazenar seu conte\u00fado no Couchbase Capella.<\/span><\/p>\n<h2>Etapa 1 - Criar um formul\u00e1rio HTML<\/h2>\n<p><span style=\"font-weight: 400;\">Inspirando-me bastante no exemplo de pesquisa do FreeCodeCamp (copiar, colar e aparar), obtive o seguinte formul\u00e1rio HTML. Ele \u00e9 um pouco mais simples do que o original.<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n&nbsp;&nbsp;&lt;head&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;link rel=&quot;stylesheet&quot; href=&quot;.\/styles.css&quot; \/&gt;\r\n&nbsp;&nbsp;&lt;\/head&gt;\r\n&nbsp;&nbsp;&lt;body&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class=&quot;container&quot;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;header class=&quot;header&quot;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h1 id=&quot;title&quot; class=&quot;text-center&quot;&gt;Formul&aacute;rio de pesquisa&lt;\/h1&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;p id=&quot;description&quot; class=&quot;description text-center&quot;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thank you for taking the time to help us improve the platform\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/p&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/header&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;form id=&quot;survey-form&quot; action=&quot;&quot;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class=&quot;form-group&quot;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;label id=&quot;name-label&quot; for=&quot;name&quot;&gt;Nome&lt;\/label&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type=&quot;text&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name=&quot;name&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id=&quot;name&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class=&quot;form-control&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;placeholder=&quot;Enter your name&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;required\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/div&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class=&quot;form-group&quot;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;label id=&quot;number-label&quot; for=&quot;number&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&gt;Idade&lt;span class=&quot;clue&quot;&gt;(opcional)&lt;\/span&gt;&lt;\/label\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type=&quot;number&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name=&quot;age&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id=&quot;number&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min=&quot;10&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max=&quot;99&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class=&quot;form-control&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;placeholder=&quot;Age&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/div&gt;\r\n\r\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class=&quot;form-group&quot;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;p&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Would you recommend this awesome survey to a Friend ?\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/p&gt;\r\n\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;label\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&gt;&lt;input\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name=&quot;recommend&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=&quot;recommend&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type=&quot;checkbox&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class=&quot;input-checkbox&quot;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&gt;sim&lt;\/label\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/div&gt;\r\n\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class=&quot;form-group&quot;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;button type=&quot;submit&quot; id=&quot;submit&quot; class=&quot;submit-button&quot;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Enviar\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/button&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/div&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input type=&quot;hidden&quot; name=&quot;trp-form-language&quot; value=&quot;pt&quot;\/&gt;&lt;\/form&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/div&gt;\r\n&nbsp;&nbsp;&lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p><span style=\"font-weight: 400;\">O <em>styles.css<\/em> \u00e9 exatamente o mesmo que o original. <a href=\"https:\/\/survey-form.freecodecamp.rocks\/\">Abra aqui<\/a> para ver o formul\u00e1rio de pesquisa em a\u00e7\u00e3o. Voc\u00ea pode abrir o<\/span><span style=\"font-weight: 400;\"> em seu navegador, clique com o bot\u00e3o direito do mouse na p\u00e1gina e voc\u00ea ver\u00e1 algo como <strong>Exibir fonte da p\u00e1gina<\/strong> ou <strong>inspecionar<\/strong>. Clique nele e isso abrir\u00e1 um painel que mostra o c\u00f3digo da p\u00e1gina. Enquanto estiver nessa exibi\u00e7\u00e3o, voc\u00ea poder\u00e1 clicar em um link como <\/span><em><span style=\"font-weight: 400;\">style.css<\/span><\/em><span style=\"font-weight: 400;\"> ou clique no \u00edcone <strong>estilos<\/strong>\u00a0para visualizar o CSS aplicado a determinados elementos tamb\u00e9m.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Para testar esse exemplo de c\u00f3digo, voc\u00ea pode primeiro clonar esse reposit\u00f3rio no seu computador local usando o terminal ou pode baix\u00e1-lo como um arquivo zip.)<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/user-images.githubusercontent.com\/60084237\/260500053-9b4fb80b-f98e-4a0a-9ff0-09e76bede954.png\" alt=\"Screenshot of button in github where you can clone or download code\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Acesse seu navegador e, na barra superior, selecione <\/span><strong>arquivo<\/strong><span style=\"font-weight: 400;\">, <\/span><strong>aberto<\/strong><span style=\"font-weight: 400;\">e, em seguida, selecione a op\u00e7\u00e3o <em>index.html<\/em> da pasta (ou pasta zip) que foi baixada. D\u00ea uma olhada no URL do seu navegador, que mostra um caminho para um arquivo local. E voc\u00ea deve ver algo como isto, que n\u00e3o faz nada quando voc\u00ea clica em enviar.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/htmlform.png\" alt=\"The screenshot of the survey from created during the freecode camp Survery lesson\" \/><\/p>\n<p><span style=\"font-weight: 400;\">A quest\u00e3o ent\u00e3o \u00e9: como implant\u00e1-lo na Internet, como fazer com que ele fa\u00e7a alguma coisa? Precisamos de algum c\u00f3digo de backend para ser executado ap\u00f3s o clique. E, em seguida, fazer com que esse c\u00f3digo armazene o conte\u00fado do formul\u00e1rio no banco de dados.<\/span><\/p>\n<h2>Etapa 2 - Git, Github, Netlify<\/h2>\n<p><span style=\"font-weight: 400;\">Vamos come\u00e7ar implantando esse formul\u00e1rio ao vivo na Internet. Para isso, usaremos o Netlify. A primeira coisa a fazer \u00e9 verificar se temos o arquivo <\/span><a href=\"https:\/\/docs.netlify.com\/cli\/get-started\/\"><span style=\"font-weight: 400;\">CLI da Netlify<\/span><\/a><span style=\"font-weight: 400;\"> dispon\u00edvel e que estamos conectados. Se ele n\u00e3o estiver instalado, o caminho mais r\u00e1pido \u00e9 digitar em seu terminal:<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">npm install netlify-cli -g<\/pre>\n<p><span style=\"font-weight: 400;\">Voc\u00ea encontrar\u00e1 mais detalhes na se\u00e7\u00e3o <a href=\"https:\/\/docs.netlify.com\/cli\/get-started\/\">Documentos de introdu\u00e7\u00e3o \u00e0 Netlify<\/a>.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Digita\u00e7\u00e3o <\/span><em><span style=\"font-weight: 400;\">vers\u00e3o netlify<\/span><\/em><span style=\"font-weight: 400;\"> em meu terminal atualmente me d\u00e1 <\/span><em><span style=\"font-weight: 400;\">netlify-cli\/15.6.0 win32-x64 node-v18.5.0<\/span><\/em><span style=\"font-weight: 400;\">. Portanto, sei que ele est\u00e1 instalado e pronto.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Em seguida, a pr\u00f3xima coisa a fazer \u00e9 digitar <\/span><em><span style=\"font-weight: 400;\">login na netlify<\/span><\/em><span style=\"font-weight: 400;\"> em seu terminal. Voc\u00ea ser\u00e1 direcionado para o formul\u00e1rio de login do Netflify.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Agora tudo deve estar pronto para passar para a fase de implementa\u00e7\u00e3o. Mas s\u00f3 para ter certeza, vamos testar as coisas localmente. Porque \u00e9 isso que a maioria dos desenvolvedores faz. Para isso, digite <\/span><span style=\"font-weight: 400;\">desenvolvimento da netlify<\/span><span style=\"font-weight: 400;\"> em seu terminal.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Ele deve exibir o seguinte no terminal e abrir o formul\u00e1rio no navegador.<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">\u25c8 Netlify Dev \u25c8\r\n\u25c8 Ignored general context env var: LANG (defined in process)\r\n\u25c8 No app server detected. Using simple static server\r\n\u25c8 Unable to determine public folder to serve files from. Using current working directory\r\n\u25c8 Setup a netlify.toml file with a [dev] section to specify your dev server settings.\r\n\u25c8 See docs at: https:\/\/cli.netlify.com\/netlify-dev#project-detection\r\n\u25c8 Running static server from \"freecodecamp-survey\"\r\n\u25c8 Setting up local development server\r\n\r\n\u25c8 Static server listening to 3999\r\n\r\nAdding local .netlify folder to .gitignore file...\r\n\r\n\u00a0\u00a0\u00a0\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\r\n\u00a0\u00a0\u00a0\u2502 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2502\r\n\u00a0\u00a0\u00a0\u2502 \u00a0 \u25c8 Server now ready on https:\/\/localhost:8888 \u00a0 \u2502\r\n\u00a0\u00a0\u00a0\u2502 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2502\r\n\u00a0\u00a0\u00a0\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/pre>\n<p><span style=\"font-weight: 400;\">Se voc\u00ea der uma olhada na barra de URL do navegador novamente, ver\u00e1 que ela \u00e9 diferente. Parece um endere\u00e7o de site da Web, n\u00e3o um arquivo local. Parab\u00e9ns, voc\u00ea acabou de executar seu primeiro servidor local, servindo seu arquivo HTML e CSS, usando N<\/span><span style=\"font-weight: 400;\">etlify dev<\/span><span style=\"font-weight: 400;\">! Voc\u00ea tem um site em execu\u00e7\u00e3o em sua m\u00e1quina. Agora vamos torn\u00e1-lo acess\u00edvel a todos na Internet, tanto o c\u00f3digo-fonte quanto o pr\u00f3prio site.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">V\u00e1 para o GitHub (ou GitLab, ou Heptapod, ou qualquer outra solu\u00e7\u00e3o de hospedagem de c\u00f3digo-fonte, existem outras por a\u00ed! Acesse<\/span><a href=\"https:\/\/github.com\/new\"> <span style=\"font-weight: 400;\">https:\/\/github.com\/new<\/span><\/a><span style=\"font-weight: 400;\"> para o Github. Agora voc\u00ea est\u00e1 no assistente de cria\u00e7\u00e3o do reposit\u00f3rio. Eu s\u00f3 configurei minha organiza\u00e7\u00e3o, o nome do meu reposit\u00f3rio e uma descri\u00e7\u00e3o, depois cliquei no bot\u00e3o <\/span><i><span style=\"font-weight: 400;\">Criar reposit\u00f3rio<\/span><\/i><span style=\"font-weight: 400;\"> bot\u00e3o.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/githubRepoCreation.png\" alt=\"A screenshot of Github's repository creation wizard\" \/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/intialGithubRepo.png\" alt=\"A screenshot of a newly intitialized Github repo\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Ele fornecer\u00e1 todas as instru\u00e7\u00f5es necess\u00e1rias para converter sua pasta de trabalho em uma pasta <em>git<\/em> e vincule-o ao seu projeto do GitHub. Foi isso que digitei no terminal (voc\u00ea pode copiar e colar o texto abaixo no terminal ou pressionar Enter ap\u00f3s cada linha do texto abaixo para execut\u00e1-lo. Observe que ser\u00e1 necess\u00e1rio alterar a linha 6 para que seja o URL do reposit\u00f3rio do projeto) Observe que voc\u00ea ter\u00e1 que alterar a linha 6 para que seja o URL do reposit\u00f3rio do projeto):<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">echo \"# myproject\" &gt;&gt; README.md\r\ngit init\r\ngit add README.md\r\ngit commit -m \"first commit\"\r\ngit branch -M main\r\ngit remote add origin https:\/\/github.com\/ldoguin\/myproject.git\r\ngit push -u origin main<\/pre>\n<p><span style=\"font-weight: 400;\">Esta \u00e9 a sa\u00edda do terminal resultante:<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">[C:\\Code\\Couchbase\\myproject] $ echo \"# myproject\" &gt;&gt; README.md\r\n[C:\\Code\\Couchbase\\myproject] $ ls\r\n\r\n\u00a0\u00a0\u00a0\u00a0Directory: C:\\Code\\Couchbase\\myproject\r\n\r\nMode \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 LastWriteTime \u00a0 \u00a0 \u00a0 \u00a0 Length Name\r\n---- \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ------------- \u00a0 \u00a0 \u00a0 \u00a0 ------ ----\r\n-a----\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 8\/4\/2023\u00a0 12:11 PM \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 28 README.md\r\n\r\n[C:\\Code\\Couchbase\\myproject] $ git init\r\nhint: Using 'master' as the name for the initial branch. This default branch name\r\nhint: is subject to change. To configure the initial branch name to use in all\r\nhint: of your new repositories, which will suppress this warning, call:\r\nhint:\r\nhint: \u00a0 git config --global init.defaultBranch &lt;name&gt;\r\nhint:\r\nhint: Names commonly chosen instead of 'master' are 'main', 'trunk' and\r\nhint: 'development'. The just-created branch can be renamed via this command:\r\nhint:\r\nhint: \u00a0 git branch -m &lt;name&gt;\r\nInitialized empty Git repository in C:\/Users\/Laurent Doguin\/Documents\/Couchbase\/myproject\/.git\/\r\n[C:\\Code\\Couchbase\\myproject] $ git config --global init.defaultBranch main\r\n[C:\\Code\\Couchbase\\myproject] $ git branch -m main\r\n[C:\\Code\\Couchbase\\myproject] $ git add .\\README.md .\\index.html .\\styles.css\r\n[C:\\Code\\Couchbase\\myproject] $ git commit -m \"first commit\"\r\n[main (root-commit) 356ece7] first commit\r\n\u00a03 files changed, 245 insertions(+)\r\n\u00a0create mode 100644 README.md\r\n\u00a0create mode 100644 index.html\r\n\u00a0create mode 100644 styles.css\r\n[C:\\Code\\Couchbase\\myproject] $ git remote add origin https:\/\/github.com\/ldoguin\/myproject.git\r\n[C:\\Code\\Couchbase\\myproject] $ git push -u origin main\r\nEnumerating objects: 5, done.\r\nCounting objects: 100% (5\/5), done.\r\nDelta compression using up to 8 threads\r\nCompressing objects: 100% (4\/4), done.\r\nWriting objects: 100% (5\/5), 1.95 KiB | 999.00 KiB\/s, done.\r\nTotal 5 (delta 0), reused 0 (delta 0), pack-reused 0\r\nTo https:\/\/github.com\/ldoguin\/myproject.git\r\n\u00a0* [new branch]\u00a0 \u00a0 \u00a0 main -&gt; main\r\nbranch 'main' set up to track 'origin\/main'.\r\n[C:\\Code\\Couchbase\\myproject] $<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Agora, se eu voltar \u00e0 p\u00e1gina do Github e recarreg\u00e1-la, verei o seguinte:<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/firstCommitReo.png\" alt=\"A screenshot of the github repository after an intial commit was pushed\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Parab\u00e9ns, seu c\u00f3digo agora est\u00e1 dispon\u00edvel no Github, para que todos possam ver, aprender e contribuir. Agora \u00e9 hora da produ\u00e7\u00e3o! Vamos colocar esse site no ar \ud83d\udcaa<\/span><\/p>\n<p><span style=\"font-weight: 400;\">V\u00e1 em frente e visite<\/span><a href=\"https:\/\/app.netlify.com\/start\/deploy\"> <span style=\"font-weight: 400;\">https:\/\/app.netlify.com\/start\/deploy<\/span><\/a><span style=\"font-weight: 400;\">. Isso o levar\u00e1 ao novo assistente de projeto do Netify. Voc\u00ea ver\u00e1 v\u00e1rios bot\u00f5es para ajud\u00e1-lo a come\u00e7ar, GitHub, GitLab, Bitbucket, AzureDevops. Vamos clicar no GitHub.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/netlifyWizard.png\" alt=\"A screenshot of the Netlify Wizard for new project creation\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Voc\u00ea ver\u00e1 algumas janelas solicitando que voc\u00ea vincule seu perfil do GitHub ao Netlify. V\u00e1 em frente e prossiga, e voc\u00ea ser\u00e1 levado \u00e0 p\u00e1gina a seguir.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/netlifyWizard2.png\" alt=\"A screenshot of the second step of Netlify's project creation wizard after picking Github\" \/><\/p>\n<p><span style=\"font-weight: 400;\">O Netlify est\u00e1 me dizendo que n\u00e3o tenho nenhum aplicativo Netlify instalado em nenhuma organiza\u00e7\u00e3o do GitHub. Clique em <\/span><strong>Configurar o Netlify no GitHub<\/strong><span style=\"font-weight: 400;\">Ele abrir\u00e1 uma janela pop-up solicitando que voc\u00ea selecione a organiza\u00e7\u00e3o do GitHub na qual deseja instalar o Netlify e o reposit\u00f3rio ao qual deseja dar acesso.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/ghAuthz.png\" alt=\"A screenshot of Github's authorization matrix\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Deixo o padr\u00e3o e prossigo para a pr\u00f3xima etapa. De agora em diante, voc\u00ea dever\u00e1 ver todos os reposit\u00f3rios em sua conta do GitHub.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/NetlifyProjectList.png\" alt=\"A screenshot of Netlify's project List showing linked Github project \" \/><\/p>\n<p><span style=\"font-weight: 400;\">Deixarei o padr\u00e3o e clicarei em <\/span><span style=\"font-weight: 400;\"><strong>Implementar <\/strong><\/span><span style=\"font-weight: 400;\"><strong>meu projeto<\/strong><\/span><i><span style=\"font-weight: 400;\">:<\/span><\/i><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/netlifyConfigureroject.png\" alt=\"A screenshot of the default Netlify project configuration\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Voc\u00ea ver\u00e1 um link para seu site rec\u00e9m-implantado na Internet, que para mim \u00e9 <\/span><em><span style=\"font-weight: 400;\">https:\/\/jolly-sfogliatella-3e6c07.netlify.app\/<\/span><\/em><span style=\"font-weight: 400;\">. A Netlify fornece um ambiente de sandboxes sob o <\/span><em><span style=\"font-weight: 400;\">netlify.app<\/span><\/em><span style=\"font-weight: 400;\"> para que voc\u00ea possa implementar coisas sem ter seu pr\u00f3prio nome de dom\u00ednio.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/netlifyProjectCreatedWiz.png\" alt=\"A screenshot of a newly created Project\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Parab\u00e9ns, seu site agora est\u00e1 no ar na Internet. Reserve um minuto para comemorar \ud83c\udf89.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Agora, podemos vincular esse projeto Netlify digitando <\/span><em><span style=\"font-weight: 400;\">link netlify<\/span><\/em><span style=\"font-weight: 400;\"> no terminal. Ser\u00e1 oferecida uma lista de op\u00e7\u00f5es. Selecione a op\u00e7\u00e3o padr\u00e3o, que deve ser <\/span><em><span style=\"font-weight: 400;\">Usar a origem remota atual do git (https:\/\/github.com\/yourOrg\/yourProject)<\/span><\/em><span style=\"font-weight: 400;\">. Como voc\u00ea fez a implanta\u00e7\u00e3o por meio do GitHub, o Netlify tem as informa\u00e7\u00f5es do git do seu reposit\u00f3rio e pode inferir qual projeto usar (e tamb\u00e9m, nesse ponto, voc\u00ea provavelmente tem apenas um projeto). Esta \u00e9 a apar\u00eancia do resultado para mim:<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">[C:\\Code\\Couchbase\\myproject] $ netlify link\r\n\r\nnetlify link will connect this folder to a site on Netlify\r\n\r\n? How do you want to link this folder to a site? Use current git remote origin (https:\/\/github.com\/ldoguin\/myproject)\r\n\r\nLooking for sites connected to 'https:\/\/github.com\/ldoguin\/myproject'...\r\n\r\nDirectory Linked\r\n\r\nAdmin url: https:\/\/app.netlify.com\/sites\/jolly-sfogliatella-3e6c07\r\nSite url:\u00a0 https:\/\/jolly-sfogliatella-3e6c07.netlify.app\r\n\r\nYou can now run other `netlify` cli commands in this directory\r\n[C:\\Code\\Couchbase\\myproject] $<\/pre>\n<p>Podemos tentar algumas coisas agora. Vou adicionar um emoji \ud83d\udc3c ao meu formul\u00e1rio, porque n\u00e3o. Em <em>index.html<\/em>Estou modificando a linha 9 a partir disso: <em>&lt;h1 id=&quot;&rdquo;title&rdquo;&quot; class=&quot;&rdquo;text-center&rdquo;&quot;&gt;Formul&aacute;rio de pesquisa&lt;\/h1&gt;<\/em> para isso <em>&lt;h1 id=&quot;&rdquo;title&rdquo;&quot; class=&quot;&rdquo;text-center&rdquo;&quot;&gt;Formul&aacute;rio de pesquisa \ud83d\udc3c&lt;\/h1&gt;<\/em><\/p>\n<p><span style=\"font-weight: 400;\">Em seguida, salvo o arquivo e envio essas altera\u00e7\u00f5es para o Github. Em seguida, no terminal, digito <\/span><em><span style=\"font-weight: 400;\">netlify open:site<\/span><\/em><span style=\"font-weight: 400;\">:<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">[C:\\Code\\Couchbase\\myproject] $ git add .\\index.html\r\n[C:\\Code\\Couchbase\\myproject] $ git commit -m\"Panda\"\r\n[main caa6f87] Panda\u00a0\r\n\u00a01 file changed, 1 insertion(+), 1 deletion(-)\r\n[C:\\Code\\Couchbase\\myproject] $ git push\r\nEnumerating objects: 5, done.\r\nCounting objects: 100% (5\/5), done.\r\nDelta compression using up to 8 threads\r\nCompressing objects: 100% (3\/3), done.\r\nWriting objects: 100% (3\/3), 360 bytes | 180.00 KiB\/s, done.\r\nTotal 3 (delta 1), reused 0 (delta 0), pack-reused 0\r\nremote: Resolving deltas: 100% (1\/1), completed with 1 local object.\r\nTo https:\/\/github.com\/ldoguin\/myproject.git\r\n\u00a0\u00a0\u00a0356ece7..8a2ebe2\u00a0 main -&gt; main\r\n[C:\\Code\\Couchbase\\myproject] $ netlify open:site\u00a0\u00a0\r\nOpening \"jolly-sfogliatella-3e6c07\" site url:\r\n&gt; https:\/\/jolly-sfogliatella-3e6c07.netlify.app<\/pre>\n<p>Algo muito legal est\u00e1 acontecendo. Como seu reposit\u00f3rio do GitHub est\u00e1 vinculado ao Netlify, uma nova implanta\u00e7\u00e3o ser\u00e1 feita automaticamente pelo Netlify. Portanto, ao abrir o site, voc\u00ea ver\u00e1 o Panda &lt;3.<\/p>\n<p><span style=\"font-weight: 400;\">Nesse ponto, temos um reposit\u00f3rio do Github que cont\u00e9m nosso c\u00f3digo, que \u00e9 integrado ao Netlify, que criar\u00e1 automaticamente uma nova implanta\u00e7\u00e3o quando voc\u00ea enviar um novo c\u00f3digo. E tamb\u00e9m temos um reposit\u00f3rio <\/span><span style=\"font-weight: 400;\">netlify<\/span><span style=\"font-weight: 400;\"> CLI em nossa pasta de trabalho. Estamos prontos para escrever o c\u00f3digo de backend!<\/span><\/p>\n<h2>Etapa 3 - Backend<\/h2>\n<p><span style=\"font-weight: 400;\">Neste cap\u00edtulo, responderemos \u00e0 seguinte pergunta: O que acontece quando algu\u00e9m preenche o formul\u00e1rio e clica em <strong>enviar<\/strong> ?<\/span><\/p>\n<p><span style=\"font-weight: 400;\">A resposta neste momento \u00e9: Nada. Vamos mudar isso. Escrevendo um pouco de JavaScript. Vamos exibir um alerta pop-up quando algu\u00e9m inserir informa\u00e7\u00f5es v\u00e1lidas e clicar em <strong>Enviar<\/strong>. Em seu <em>index.html<\/em> voc\u00ea colocar\u00e1 o seguinte <em>&lt;script&gt;<\/em> c\u00f3digo entre a \u00faltima tag div de fechamento <\/span><em><span style=\"font-weight: 400;\">&lt;\/div&gt;<\/span><\/em><span style=\"font-weight: 400;\"> e antes da tag de fechamento do corpo <\/span><em><span style=\"font-weight: 400;\">&lt;\/body&gt;<\/span><\/em><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">&lt;script&gt;\r\n\u00a0\u00a0const form = document.getElementById('survey-form'); &lt;1&gt;\r\n\u00a0\u00a0form.addEventListener('submit', handleForm); &lt;2&gt;\r\n\r\n\u00a0\u00a0async function handleForm(e) {\r\n\u00a0\u00a0\u00a0\u00a0e.preventDefault() &lt;3&gt;\r\n\u00a0\u00a0\u00a0\u00a0alert(\"Form Submission !\") &lt;4&gt;\r\n\u00a0\u00a0}\r\n\r\n\u00a0\u00a0&lt;\/script&gt;<\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"nums:false lang:default decode:true\">&lt;1&gt; Get the Dom element representing the form by using its id\r\n&lt;2&gt; Each time the submit event occurs, run the handleForm function\r\n&lt;3&gt; The natural behavior of a form submission is to reload the page, we don't need that, hence we prevent the default behavior to happen\r\n&lt;4&gt; The alert function display a popup with a message<\/pre>\n<p>Se voc\u00ea salvar seu c\u00f3digo e recarregar a p\u00e1gina, preencha o formul\u00e1rio e clique em <strong>enviar<\/strong>voc\u00ea ver\u00e1 algo parecido com isto:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/formSubmission.png\" alt=\"A screenshot of a sucessfull form submission\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Agora que temos algo acontecendo quando um usu\u00e1rio envia o formul\u00e1rio, vamos avan\u00e7ar um pouco mais. Queremos examinar o conte\u00fado do formul\u00e1rio e nos certificar de que podemos obter os dados corretos no JSON. Queremos uma string para o nome, um n\u00famero inteiro para a idade e um booleano para a recomenda\u00e7\u00e3o.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">E acontece que a caixa de sele\u00e7\u00e3o HTML n\u00e3o est\u00e1 funcionando bem. O valor que ela fornece por padr\u00e3o \u00e9 nenhum valor e, quando marcada, fornece o conte\u00fado do campo de valor. Vamos adicionar outro campo de entrada, oculto, para garantir que o valor padr\u00e3o seja False.<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id=\"hiddenRecommend\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name=\"recommend\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value=\"false\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=\"hidden\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id=\"recommend\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name=\"recommend\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value=\"true\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=\"checkbox\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0class=\"input-checkbox\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;yes&lt;\/label&gt;<\/pre>\n<p><span style=\"font-weight: 400;\">Agora, com rela\u00e7\u00e3o ao c\u00f3digo JavaScript, h\u00e1 algumas novas linhas interessantes a serem analisadas.<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\"> const form = document.getElementById('survey-form');\r\n\u00a0\u00a0form.addEventListener('submit', handleForm);\r\n\r\n\u00a0\u00a0async function handleForm(e) { &lt;1&gt;\r\n\u00a0\u00a0\u00a0\u00a0e.preventDefault()\r\n\u00a0\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0const data = new FormData(e.target); &lt;1&gt;\r\n\u00a0\u00a0\u00a0\u00a0const value = Object.fromEntries(data.entries()); &lt;2&gt;\r\n\u00a0\u00a0\u00a0\u00a0const details = `name: ${value.name}\\nage: ${value.age}\\nrecommend: ${value.recommend}`; &lt;3&gt;\r\n\u00a0\u00a0\u00a0\u00a0console.log(details); &lt;4&gt;\r\n\u00a0\u00a0}<\/pre>\n<pre class=\"nums:false lang:default decode:true\">&lt;1&gt; The parameter of the handleForm function is an object(e) with a field called target. This target can be transform into a FormData object.\r\n&lt;2&gt; The FormData object can be transformed into a JSON object.\r\n&lt;3&gt; Now that we have a JSON object we can print out the values we are interested in.\r\n&lt;4&gt; This time instead of displaying an alert box, we are logging the details string to the console. The console can be accessed through your browser's dev tools. It is great for debugging.<\/pre>\n<p>Com isso resolvido, vamos levar a s\u00e9rio e come\u00e7ar a criar uma fun\u00e7\u00e3o Netlify. Entrar <em>fun\u00e7\u00e3o netlify:create<\/em> em seu terminal. Voc\u00ea dever\u00e1 ver algo como:<\/p>\n<pre class=\"nums:false lang:default decode:true\">[C:\\Code\\Couchbase\\myproject] $ netlify function:create\r\n? Select the type of function you'd like to create Serverless function (Node\/Go)\r\n\u25c8 functions directory not specified in netlify.toml or UI settings\r\n? Enter the path, relative to your site\u2019s base directory in your repository, where your functions should live: netlify\/functions\r\n\u25c8 updating site settings with netlify\/functions\r\n\u25c8 functions directory netlify\/functions updated in site settings\r\n\u25c8 functions directory netlify\/functions does not exist yet, creating it...\r\n\u25c8 functions directory netlify\/functions created\r\n? Select the language of your function JavaScript\r\n? Pick a template javascript-hello-world\r\n? Name your function: saveform\r\n\u25c8 Creating function saveform\r\n\u25c8 Created netlify\\functions\\saveform\\saveform.js\r\n[C:\\Code\\Couchbase\\myproject] $<\/pre>\n<p><span style=\"font-weight: 400;\">Selecione <strong>Sem servidor<\/strong> deixa o padr\u00e3o para a pr\u00f3xima pergunta sobre o caminho, mant\u00e9m o JavaScript como a linguagem, mant\u00e9m o padr\u00e3o <em>mundo do inferno<\/em> e, em seguida, d\u00ea um nome \u00e0 sua fun\u00e7\u00e3o. A minha se chama <\/span><em><span style=\"font-weight: 400;\">salvar formul\u00e1rio<\/span><\/em><span style=\"font-weight: 400;\">. Isso gerar\u00e1 novos arquivos na pasta netlify. Se voc\u00ea executar <\/span><em><span style=\"font-weight: 400;\">desenvolvimento da netlify<\/span><\/em><span style=\"font-weight: 400;\"> agora, voc\u00ea ver\u00e1 novas linhas nos registros:<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">Loaded function saveform https:\/\/localhost:8888\/.netlify\/functions\/saveform.\r\n\u25c8 Functions server is listening on 62431<\/pre>\n<p>Isso significa que nosso servidor de desenvolvimento netlify tamb\u00e9m est\u00e1 atendendo \u00e0 nossa fun\u00e7\u00e3o rec\u00e9m-criada. D\u00ea uma olhada no arquivo rec\u00e9m-gerado <em>.\/netlify\/functions\/saveform\/saveform.js<\/em>.<\/p>\n<pre class=\"nums:false lang:default decode:true\">\/\/ Docs on event and context https:\/\/docs.netlify.com\/functions\/build\/#code-your-function-2\r\nconst handler = async (event) =&gt; { &lt;1&gt;\r\n\u00a0\u00a0try {\r\n\u00a0\u00a0\u00a0\u00a0const subject = event.queryStringParameters.name || 'World' &lt;2&gt;\r\n\u00a0\u00a0\u00a0\u00a0return {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0statusCode: 200,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0body: JSON.stringify({ message: `Hello ${subject}` }), &lt;3&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ \/\/ more keys you can return:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ headers: { \"headerName\": \"headerValue\", ... },\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ isBase64Encoded: true,\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\u00a0\u00a0} catch (error) {\r\n\u00a0\u00a0\u00a0\u00a0return { statusCode: 500, body: error.toString() } &lt;4&gt;\r\n\u00a0\u00a0}\r\n}\r\n\r\nmodule.exports = { handler }<\/pre>\n<pre class=\"nums:false lang:default decode:true\">&lt;1&gt; the signature of the function is aysynchronous (the async keyword),and has an event parameter. Asynchronous means some code inside the function can be asynchronous and we can wait for the code to be executed with the await keyword, instead of managing the JavaScript Promess object traditionally returned by async functions.\r\n&lt;2&gt; the `event` object has some properties and methods, like `queryStringParameters` that allows us to get the name query param\r\n&lt;3&gt; this function must return a JSON object with an HTTP status code and an Object body. If everything worked well, we return a JSON body containing a message field and the code 200. Code starting with 2 means things went well.\r\n&lt;4&gt; If things went wrong, we return the status code 500. Code starting with 5 means something went wrong on the server. And the body field will contain the error.<\/pre>\n<p>Vamos test\u00e1-lo chamando essa fun\u00e7\u00e3o quando o usu\u00e1rio clicar em <strong>enviar<\/strong>. Basta adicionar o seguinte c\u00f3digo ap\u00f3s o \u00faltimo <em>console.log<\/em> ligar:<\/p>\n<pre class=\"nums:false lang:default decode:true\">  \u00a0\u00a0console.log(details);\r\n\u00a0\r\n \u00a0\u00a0\u00a0const response = await fetch(\"\/.netlify\/functions\/saveform\", { &lt;1&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0method: 'GET', &lt;2&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0headers: { &lt;3&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'Content-Type': 'application\/json',\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\r\n\u00a0\u00a0\u00a0\u00a0})\r\n\u00a0\u00a0\u00a0\u00a0if (response.status == 200) { &lt;4&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0console.log(await response.text());\r\n\u00a0\u00a0\u00a0\u00a0}<\/pre>\n<pre class=\"nums:false lang:default decode:true\">&lt;1&gt; fetch is the method you can call to send an HTTP request to a server. Here we are sending a request to `\/.netlify\/functions\/saveform`. Notice the await keyword that means this method usually returns a promess. Here we are just assign the result of the promess to the field response.\r\n&lt;2&gt; HTTP request have methods, sometime also known as HTTP verbs. Here we are not modifying anything on the server, we are retrieving information, so we are using the method GET\r\n&lt;3&gt; HTTP requests have [headers](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Content-Type). They provide additional metadata like the Content-type, here set to `application\/json`. What it means is that we are manipulating JSON. `application\/text` would mean we are manipulating any form of text. These are called [Mime types or Media type](https:\/\/developer.mozilla.org\/en-US\/docs\/Glossary\/MIME_type).\r\n&lt;4&gt; We are testing the status code returned by the server. If it's 200, it means everything went well. We have a message to display in the console.<\/pre>\n<p><span style=\"font-weight: 400;\">Adicionar, confirmar e enviar. <\/span><em><span style=\"font-weight: 400;\">netlify open:admin<\/span><\/em><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/netlifyDeployList.png\" alt=\"A screenshot showing the Netlify site administrator overview, with the list of all deployments already done\" \/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/netlifyFunctionReturnCall.png\" alt=\"A screenshot of the form page and the developer tools opened, showing the message returned by the Netlify function\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Neste ponto, voc\u00ea tem um frontend e um backend implantados na Internet. Mas tudo o que estamos fazendo \u00e9 chamar a fun\u00e7\u00e3o padr\u00e3o criada pelo assistente do Netlify. A pr\u00f3xima etapa \u00e9 enviar o conte\u00fado do formul\u00e1rio para essa fun\u00e7\u00e3o e armazen\u00e1-lo em um banco de dados.<\/span><\/p>\n<h2>Etapa 4 - Banco de dados<\/h2>\n<p><span style=\"font-weight: 400;\">A primeira coisa a fazer \u00e9 descobrir como enviar os detalhes do formul\u00e1rio para a fun\u00e7\u00e3o. Para isso, precisamos alterar nosso m\u00e9todo GET para um m\u00e9todo POST. Essas coisas s\u00e3o chamadas de m\u00e9todos de solicita\u00e7\u00e3o HTTP, \u00e0s vezes chamados de verbos HTTP. Voc\u00ea pode dar uma olhada na lista completa em<\/span><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Methods\"> <span style=\"font-weight: 400;\">MDN<\/span><\/a><span style=\"font-weight: 400;\">. Uma solicita\u00e7\u00e3o do m\u00e9todo Get \u00e9 usada apenas para recuperar dados. Uma solicita\u00e7\u00e3o de m\u00e9todo Post \u00e9 usada para criar ou alterar dados. \u00c9 exatamente isso que queremos. Queremos criar uma nova entrada em nosso banco de dados quando algu\u00e9m enviar um formul\u00e1rio. Uma solicita\u00e7\u00e3o HTTP tem um m\u00e9todo, alguns cabe\u00e7alhos (metadados sobre suas solicita\u00e7\u00f5es, aqui estamos dizendo que a solicita\u00e7\u00e3o ter\u00e1 conte\u00fado JSON com o cabe\u00e7alho Content-Typ) e um corpo. O corpo da nossa solicita\u00e7\u00e3o ser\u00e1 um texto JSON.<\/span><\/p>\n<pre class=\"nums:false lang:js decode:true\"> \u00a0\u00a0const response = await fetch(\"\/.netlify\/functions\/saveform\", {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0method: 'POST', &lt;1&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0headers: {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'Content-Type': 'application\/json',\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0body: JSON.stringify(value), &lt;2&gt;\r\n\u00a0\u00a0\u00a0\u00a0})<\/pre>\n<pre class=\"nums:false lang:default decode:true\">&lt;1&gt; We change the HTTP method to POST because we want to change something instead of just retrieving information. \r\n&lt;2&gt; A request can also have a body. Here we are sending a text version of our JSON object.<\/pre>\n<p><span style=\"font-weight: 400;\">Nossa solicita\u00e7\u00e3o HTTP do frontend para o backend foi alterada, agora precisamos adaptar o c\u00f3digo do backend.<\/span><\/p>\n<pre class=\"nums:false lang:js decode:true\">const handler = async (event) =&gt; {\r\n\u00a0\u00a0try {\r\n\u00a0\u00a0\u00a0\u00a0var data = JSON.parse(event.body); &lt;1&gt;\r\n\u00a0\u00a0\u00a0\u00a0return {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0statusCode: 200,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0body: JSON.stringify({ name: data.name }) &lt;2&gt;\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\u00a0\u00a0} catch (error) {\r\n\u00a0\u00a0\u00a0\u00a0return { statusCode: 500, body: error.toString() }\r\n\u00a0\u00a0}\r\n}\r\n\r\nmodule.exports = { handler }<\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"nums:false lang:default decode:true\">&lt;1&gt; The event object allows us to get the body of the request. It's text, we can parse this text into a JSON object and assign it to the field called `data`.\r\n&lt;2&gt; To make sure we did receive our JSON object, we change the returned message and use the field `data.name`.<\/pre>\n<p>Voc\u00ea dever\u00e1 ver uma mensagem diferente no console de desenvolvimento da Web, ou seja, dever\u00e1 ver <em>{\"name\": \"yourName\"}<\/em>.<\/p>\n<p><span style=\"font-weight: 400;\">Enviamos os dados do formul\u00e1rio para o backend e nos certificamos disso. Agora vamos para o lado do banco de dados. Trabalhando no Couchbase, esse \u00e9 o banco de dados que vou usar. Uma maneira simples de tentar, v\u00e1 para<\/span><a href=\"https:\/\/cloud.couchbase.com\/sign-up\"> <span style=\"font-weight: 400;\">https:\/\/cloud.couchbase.com\/sign-up<\/span><\/a><span style=\"font-weight: 400;\">Se voc\u00ea criar uma conta, ter\u00e1 uma avalia\u00e7\u00e3o de 30 dias, sem necessidade de cart\u00e3o de cr\u00e9dito.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/capellaGetStarted.png\" alt=\"A screenshot of the first Couchbase Capella Get started wizard step \" \/><\/p>\n<p><span style=\"font-weight: 400;\">Voc\u00ea pode deixar o padr\u00e3o ativado ou escolher seu provedor de nuvem favorito e a regi\u00e3o mais pr\u00f3xima. Clique em <\/span><strong><i>Implantar agora<\/i><\/strong><span style=\"font-weight: 400;\"> e aguarde a implanta\u00e7\u00e3o do seu banco de dados.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/capellaTrialHome.png\" alt=\"A screenshot of the Couchbase Capella trial home\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Duas coisas que queremos fazer a partir da\u00ed. Garantir que possamos nos conectar a esse banco de dados a partir do nosso c\u00f3digo de backend e garantir que possamos gravar os dados em algum lugar. V\u00e1 em frente e clique no bot\u00e3o <strong>Conectar<\/strong> guia.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">No Couchbase, armazenamos dados em Buckets. Por padr\u00e3o, a avalia\u00e7\u00e3o vem com um bucket de amostra de viagem pr\u00e9-importado. N\u00e3o vamos us\u00e1-lo. Em vez disso, vamos criar nosso pr\u00f3prio bucket. Clique em <\/span><strong>Configura\u00e7\u00f5es<\/strong><span style=\"font-weight: 400;\"> no menu de n\u00edvel superior, do que em <\/span><strong>Baldes<\/strong><span style=\"font-weight: 400;\"> no menu \u00e0 esquerda.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/bucketHome.png\" alt=\"A screenshot of the Bucket settings in Couchbase Capella\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Agora, clique em <\/span><strong>+ Criar balde<\/strong><span style=\"font-weight: 400;\">d\u00ea um nome a ele e deixe o restante com as configura\u00e7\u00f5es padr\u00e3o. <\/span><strong>Criar balde<\/strong><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/surveyFormBucketCreated.png\" alt=\"A screenshot of the Buckets settings home, with the newly created bucket visible\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Temos um novo Bucket, agora precisamos criar as credenciais associadas. Clique no bot\u00e3o <\/span><strong>Acesso ao banco de dados<\/strong><span style=\"font-weight: 400;\"> do que <\/span><strong>Criar acesso ao banco de dados<\/strong><span style=\"font-weight: 400;\"> bot\u00e3o.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/emptyCredentials.png\" alt=\"A screenshot of the empty Credentials settings\" \/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/credentialCreation.png\" alt=\"A screenshot fo the credentials creation detail\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Certifique-se de lembrar o nome de usu\u00e1rio e a senha e clique em <\/span><strong>Criar banco de dados<\/strong><span style=\"font-weight: 400;\">. Uma \u00faltima coisa a fazer \u00e9 permitir que esse banco de dados possa ser acessado publicamente. No momento, ele est\u00e1 oculto. Clique em <\/span><strong>Endere\u00e7os IP permitidos<\/strong><span style=\"font-weight: 400;\">do que <\/span><strong>Adicionar IP permitido<\/strong><span style=\"font-weight: 400;\">. Clique em <\/span><span style=\"font-weight: 400;\"><strong>Permitir acesso<\/strong> <\/span><strong>De qualquer lugar<\/strong><span style=\"font-weight: 400;\">e siga as instru\u00e7\u00f5es. O formul\u00e1rio dever\u00e1 ser preenchido previamente e, em seguida, clique no bot\u00e3o <\/span><strong>Adicionar IP permitido<\/strong><span style=\"font-weight: 400;\"> bot\u00e3o. Voc\u00ea pode achar que isso \u00e9 um pouco complicado. Por que ele n\u00e3o \u00e9 o padr\u00e3o?<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/addAllowedIp.png\" alt=\"A screenshot of the Allow Access from Anywhere popup\" \/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/addedIp.png\" alt=\"A screenshot of the resuting operation with the newly added IP range\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Agora, clique no \u00edcone <\/span><strong>Conectar<\/strong><span style=\"font-weight: 400;\"> guia. Voc\u00ea ver\u00e1 a guia <em>Cadeia de conex\u00e3o<\/em>selecione as credenciais do banco de dados, altere o idioma para Node e ele nos dar\u00e1 as instru\u00e7\u00f5es corretas para nos conectarmos ao banco de dados a partir do nosso c\u00f3digo de backend.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/ldoguin\/freecodecamp-survey\/raw\/main\/images\/connectInstructions.png\" alt=\"A screenshot of the SDK connection instructions, with doc and code\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Podemos copiar e colar isso em nosso c\u00f3digo de fun\u00e7\u00e3o e adicionar mais algumas coisas:<\/span><\/p>\n<pre class=\"nums:false lang:js decode:true\">const crypto = require(\"crypto\"); &lt;1&gt;\u00a0\r\nconst couchbase = require(\"couchbase\"); &lt;2&gt;\r\n\r\nconst handler = async (event) =&gt; {\r\n\u00a0\u00a0try {\r\n         const clusterConnStr = \"couchbases:\/\/cb.ar0qqwli6cczm1u.cloud.couchbase.com\"; \/\/ Replace this with Connection String &lt;3&gt;\r\n         const username = \"Adminstrator\"; \/\/ Replace this with username from database access credentials &lt;3&gt;\r\n         const password = \"Couch#123\"; \/\/ Replace this with password from database access credentials &lt;3&gt;\r\n         \/\/ Get a reference to the cluster\r\n         const cluster = await couchbase.connect(clusterConnStr, { &lt;4&gt;\r\n         \u00a0 username: username,\r\n         \u00a0 password: password,\r\n         \u00a0 \/\/ Use the pre-configured profile below to avoid latency issues with your connection.\r\n         \u00a0 configProfile: \"wanDevelopment\",\r\n         });\r\n\r\n\u00a0\u00a0\u00a0\u00a0const bucket = cluster.bucket(\"surveyform\"); &lt;5&gt;\r\n\u00a0\u00a0\u00a0\u00a0const collection = bucket.defaultCollection(); &lt;6&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0var data = JSON.parse(event.body);\r\n\u00a0\u00a0\u00a0\u00a0let result = await collection.insert(crypto.randomUUID(), data); &lt;7&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0return {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0statusCode: 200,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0body: JSON.stringify({ name: data.name })\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\u00a0\u00a0} catch (error) {\r\n\u00a0\u00a0\u00a0\u00a0console.log(error);\r\n\u00a0\u00a0\u00a0\u00a0return { statusCode: 500, body: error.toString() }\r\n\u00a0\u00a0}\r\n}\r\n\r\nmodule.exports = { handler }<\/pre>\n<pre class=\"nums:false lang:default decode:true\">&lt;1&gt; You can see we have two new dependencies to our project. The 'crypto' package is provided by node. It allows us to generate a random identifier for our document\r\n&lt;2&gt; The 'couchbase' package is the Couchbase NodeJS SDK. It's every bit of code you need to connect to a Couchbase database. This projects are also often called drivers for other databases, or clients.<\/pre>\n<p>Para o Couchbase, voc\u00ea precisa instal\u00e1-lo. Em execu\u00e7\u00e3o <em>npm i couchbase@4.2.4<\/em> ser\u00e1 suficiente. No momento, a compatibilidade Netlify\/Couchbase \u00e9 garantida para o Couchbase vers\u00e3o 4.2.4 ou inferior. Isso se deve \u00e0 natureza do nosso SDK. Trata-se de uma interface JavaScript sobre o nosso SDK em C. E as depend\u00eancias C esperam encontrar suas depend\u00eancias de sistema na vers\u00e3o correta. No momento, o Couchbase 4.2.5 est\u00e1 esperando encontrar <em>GLIBC_29<\/em> mas ele n\u00e3o est\u00e1 dispon\u00edvel no sistema Ubuntu que executa nosso c\u00f3digo de back-end do Netlify.<\/p>\n<p><span style=\"font-weight: 400;\">Agora que temos depend\u00eancias, vamos ser expl\u00edcitos em como cri\u00e1-las. Voc\u00ea pode adicionar um <\/span><em><span style=\"font-weight: 400;\">netlify.toml<\/span><\/em><span style=\"font-weight: 400;\"> na raiz do reposit\u00f3rio com o seguinte conte\u00fado:<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">[build]\r\n\u00a0\u00a0command = \"npm install &amp;&amp; strip --strip-debug .\/node_modules\/couchbase\/build\/Release\/couchbase_impl.node\"\r\n\u00a0\u00a0publish = \".\"<\/pre>\n<p><span style=\"font-weight: 400;\">Ele est\u00e1 fazendo algumas coisas. Instalar as depend\u00eancias e remover a tabela de s\u00edmbolos de depura\u00e7\u00e3o de <\/span><em><span style=\"font-weight: 400;\">couchbase_impl.node<\/span><\/em><span style=\"font-weight: 400;\">. Esse arquivo \u00e9 a biblioteca C usada pelo nosso Node SDK. E ele \u00e9 muito grande para o Netlify no momento. Portanto, estamos removendo a bagun\u00e7a desnecess\u00e1ria proveniente do processo de compila\u00e7\u00e3o.<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">&lt;3&gt; This variables are the informations needed for the SDK to connect to the cluster. A connections string, a username and a password.\r\n&lt;4&gt; `couchbase.connect` takes the connection string as first parameter, than a JSON object with username, password and other options. Here we also give the `wanDevelopment` config profiles. It will increase the default timeout values of all Couchbase operations. Basically if your connection is slow it won't scream at you.\r\n&lt;5&gt; From the Cluster object we get a Bucket. A bucket is where we store Scopes and Collections. Here we get the `surveyform` bucket. It already has a default scope and a default collection.\r\n&lt;6&gt; From the bucket we can get the default Collection. A Collection is where we store Document, or key\/value pairs. Think of the key as the identifier of the document, and the value as your JSON data. But it could be anything else.\r\n&lt;7&gt; From the collection object, we call the insert method. It takes two parameters, the key and the value. So we call the randomUUID() method from the crypto package, to generate a random identifier. And we pass the data object as value. It contains our JSON. This function is asynchronous, it's making a request to the Couchbase Capella cluster. We await for the cluster's response.<\/pre>\n<p><span style=\"font-weight: 400;\">Agora voc\u00ea poderia adicionar os novos arquivos, fazer o commit e enviar para o GitHub. Mas isso enviaria sua senha para o GitHub. N\u00e3o queremos isso. Em vez disso, voc\u00ea pode test\u00e1-lo executando <\/span><em><span style=\"font-weight: 400;\">desenvolvimento da netlify<\/span><\/em><span style=\"font-weight: 400;\">. Continue e reenvie o formul\u00e1rio.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Se tudo correu bem, voc\u00ea gravou dados em seu banco de dados! Voc\u00ea pode verificar isso facilmente acessando a interface do usu\u00e1rio do Couchbase Capella. Clique em <\/span><strong>Ferramentas de dados<\/strong><span style=\"font-weight: 400;\">Selecione seu Bucket, Scope e collection, e voc\u00ea ver\u00e1 sua pesquisa no documento.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Isso \u00e9 \u00f3timo, voc\u00ea acabou de escrever um c\u00f3digo para conectar seu banco de dados!<\/span><\/p>\n<h2>Etapa 5 - Gerenciamento de configura\u00e7\u00e3o<\/h2>\n<p><span style=\"font-weight: 400;\">Para evitar o envio de nossas credenciais para o GitHub, usaremos vari\u00e1veis de ambiente. As vari\u00e1veis de ambiente s\u00e3o comuns a todos os sistemas operacionais e s\u00e3o a melhor maneira de gerenciar a configura\u00e7\u00e3o em diferentes ambientes (diferentes sistemas operacionais, nuvens, testes, prepara\u00e7\u00e3o, pr\u00e9-produ\u00e7\u00e3o, produ\u00e7\u00e3o, o que for adequado ao seu fluxo de trabalho).<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">....\r\nconst ENDPOINT = process.env.COUCHBASE_ENDPOINT || \"couchbase:\/\/localhost\"; &lt;1&gt;\r\nconst USERNAME = process.env.COUCHBASE_USERNAME || \"Administrator\";&lt;1&gt;\r\nconst PASSWORD = process.env.COUCHBASE_PASSWORD || \"password\";&lt;1&gt;\r\nconst BUCKET = process.env.COUCHBASE_BUCKET || \"surveyform\"&lt;1&gt;\r\nconst handler = async (event) =&gt; {\r\n\u00a0\u00a0try {\r\n        const clusterConnStr = ENDPOINT; \/\/ Replace this with Connection String\r\n        const username = USERNAME; \/\/ Replace this with username from database access credentials\r\n        const password = PASSWORD; \/\/ Replace this with password from database access credentials\r\n        \/\/ Get a reference to the cluster\r\n        const cluster = await couchbase.connect(clusterConnStr, {\r\n          usernme: username,\r\n          password: password,\r\n       \u00a0  \/\/ Use the pre-configured profile below to avoid latency issues with your connection.\r\n       \u00a0  configProfile: \"wanDevelopment\",\r\n        });\r\n\u00a0\u00a0\u00a0\u00a0const bucket = cluster.bucket(BUCKET);\r\n...<\/pre>\n<pre class=\"nums:false lang:default decode:true\">&lt;1&gt; The process object is always available with node so no need for a specific library import. Using || allows to provide a default value for each variable if they are not defined.<\/pre>\n<p><span style=\"font-weight: 400;\">No Mac ou Linux, voc\u00ea pode executar <\/span><em><span style=\"font-weight: 400;\">export MYVARIABLE=\"value\"<\/span><\/em><span style=\"font-weight: 400;\"> em seu terminal. No Windows, voc\u00ea pode executar <\/span><em><span style=\"font-weight: 400;\">$Env:MYVARIABLE=\"value\"<\/span><\/em><\/p>\n<p><span style=\"font-weight: 400;\">Para defini-los no contexto da Netlify, voc\u00ea pode acessar a interface do usu\u00e1rio e fazer isso manualmente ou usar a CLI:<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">netlify env:set COUCHBASE_ENDPOINT couchbases:\/\/cb.ar0qqwli6cczm1u.cloud.couchbase.com\r\nnetlify env:set COUCHBASE_USERNAME Administrator\r\nnetlify env:set COUCHBASE_PASSWORD password\r\nnetlify env:set COUCHBASE_BUCKET surveyform<\/pre>\n<p><span style=\"font-weight: 400;\">Agora voc\u00ea pode adicionar seus arquivos, confirmar e enviar seu c\u00f3digo. Parab\u00e9ns, voc\u00ea fez o fullstack. Back-end, front-end e banco de dados. E implantou tudo ao vivo! Mas nosso trabalho ainda n\u00e3o terminou. Ainda h\u00e1 algumas coisas que podemos fazer para tornar isso mais profissional.<\/span><\/p>\n<h2>Etapa 6 - Feedback do usu\u00e1rio<\/h2>\n<p><span style=\"font-weight: 400;\">No momento, n\u00e3o h\u00e1 muita coisa acontecendo quando o usu\u00e1rio clica no bot\u00e3o <\/span><strong>Enviar<\/strong><span style=\"font-weight: 400;\"> do nosso formul\u00e1rio. Precisamos alterar isso para que eles saibam que foram registrados com sucesso ou n\u00e3o. A primeira etapa \u00e9 verificar se h\u00e1 um erro no lado do desenvolvimento. O c\u00f3digo de status HTTP \u00e9 bem feito, qualquer coisa igual ou superior a 400 geralmente \u00e9 um erro, portanto, podemos fazer algo assim:<\/span><\/p>\n<pre class=\"nums:false lang:js decode:true\"> \u00a0\u00a0\u00a0if (response.status &gt;= 400) { &lt;1&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0console.log(\"Something when wrong\"); &lt;2&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0console.log(await response.text()); &lt;3&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return false;\r\n\u00a0\u00a0\u00a0\u00a0}<\/pre>\n<pre class=\"nums:false lang:default decode:true\">&lt;1&gt; Status code that starts with 4 usually means something went wrong on the client side. The wrong data was sent, the client does not have the right permission, the page does not exist etc... Here we test if the code is equals or higher than 400.\r\n&lt;2&gt; If it is, we log a message in the console\r\n&lt;3&gt; We also log the error message returned by the server<\/pre>\n<p>Para test\u00e1-lo, basta cometer um erro de digita\u00e7\u00e3o em algum lugar da cadeia de conex\u00e3o ou das credenciais do Couchbase. Voc\u00ea dever\u00e1 ver erros no console da Web ao clicar em <i>Enviar<\/i>. Mas o console da Web \u00e9 apenas para n\u00f3s, precisamos adicionar uma mensagem de erro ou de sucesso adequada ao nosso usu\u00e1rio.<\/p>\n<p><span style=\"font-weight: 400;\">Adicionei alguns elementos HTML de extens\u00e3o com mensagens de erro e sucesso logo antes do final do formul\u00e1rio. Observe o <em>esconder<\/em> Classe CSS que os torna invis\u00edveis por enquanto.<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">...\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/div&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;span id=&quot;form-error&quot; class=&quot;error-message hide&quot;&gt;&lt;\/span&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;span id=&quot;thank-you-message&quot; class=&quot;hide&quot;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Your participation has been recorded, thank you!.\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/span&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/form&gt;\r\n...<\/pre>\n<p><span style=\"font-weight: 400;\">E aqui est\u00e1 o CSS correspondente. Exibindo o erro em vermelho, ocultando ou exibindo um elemento, e uma bela anima\u00e7\u00e3o de fade-out, porque eu sou chique assim.<\/span><\/p>\n<pre class=\"nums:false lang:css decode:true\">.container .error-message {\r\n\u00a0\u00a0color: red;\r\n}\r\n\r\n.hide {\r\n\u00a0\u00a0display: none;\r\n}\r\n\r\n.show {\r\n\u00a0\u00a0display: block;\r\n}\r\n\r\n.fade-out {\r\n\u00a0\u00a0animation: fadeOut ease 8s;\r\n\u00a0\u00a0-webkit-animation: fadeOut ease 8s;\r\n\u00a0\u00a0-moz-animation: fadeOut ease 8s;\r\n\u00a0\u00a0-o-animation: fadeOut ease 8s;\r\n\u00a0\u00a0-ms-animation: fadeOut ease 8s;\r\n}@keyframes fadeOut {\r\n\u00a0\u00a00% {\r\n\u00a0\u00a0\u00a0\u00a0opacity:1;\r\n\u00a0\u00a0}\r\n\u00a0\u00a0100% {\r\n\u00a0\u00a0\u00a0\u00a0opacity:0;\r\n\u00a0\u00a0}\r\n}\r\n\r\n@-moz-keyframes fadeOut {\r\n\u00a0\u00a00% {\r\n\u00a0\u00a0\u00a0\u00a0opacity:1;\r\n\u00a0\u00a0}\r\n\u00a0\u00a0100% {\r\n\u00a0\u00a0\u00a0\u00a0opacity:0;\r\n\u00a0\u00a0}\r\n}\r\n\r\n@-webkit-keyframes fadeOut {\r\n\u00a0\u00a00% {\r\n\u00a0\u00a0\u00a0\u00a0opacity:1;\r\n\u00a0\u00a0}\r\n\u00a0\u00a0100% {\r\n\u00a0\u00a0\u00a0\u00a0opacity:0;\r\n\u00a0\u00a0}\r\n}\r\n\r\n@-o-keyframes fadeOut {\r\n\u00a0\u00a00% {\r\n\u00a0\u00a0\u00a0\u00a0opacity:1;\r\n\u00a0\u00a0}\r\n\u00a0\u00a0100% {\r\n\u00a0\u00a0\u00a0\u00a0opacity:0;\r\n\u00a0\u00a0}\r\n}\r\n\r\n@-ms-keyframes fadeOut {\r\n\u00a0\u00a00% {\r\n\u00a0\u00a0\u00a0\u00a0opacity:1;\r\n\u00a0\u00a0}\r\n\u00a0\u00a0100% {\r\n\u00a0\u00a0\u00a0\u00a0opacity:0;\r\n\u00a0\u00a0\u00a0\u00a0display: none;\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Agora vamos juntar tudo. As duas primeiras linhas obt\u00eam os novos elementos de extens\u00e3o que acabaram de ser adicionados. A chamada para <\/span><em><span style=\"font-weight: 400;\">form.reset()<\/span><\/em><span style=\"font-weight: 400;\"> est\u00e1 limpando todos os valores do formul\u00e1rio quando o c\u00f3digo de status da resposta retornada \u00e9 <em>200<\/em>. Depois, o resto \u00e9 brincar com as classes CSS para fazer com que a mensagem apare\u00e7a, depois desaparecer com a adi\u00e7\u00e3o da classe fade-out, depois uma fun\u00e7\u00e3o de tempo limite de 7000 ms remover\u00e1 todas as classes e ocultar\u00e1 o elemento novamente. \u00c9 praticamente a mesma coisa quando h\u00e1 um erro.<\/span><\/p>\n<pre class=\"nums:false lang:js decode:true\"> \u00a0\u00a0\u00a0const thankYouMessage = document.getElementById('thank-you-message'); &lt;1&gt;\r\n\u00a0\u00a0\u00a0\u00a0const formError = document.getElementById(\"form-error\"); &lt;1&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0if (response.status == 200) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0form.reset(); &lt;2&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0thankYouMessage.classList.add('show'); &lt;3&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0thankYouMessage.classList.add('fade-out'); &lt;3&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setTimeout(function(){thankYouMessage.classList.remove('fade-out');thankYouMessage.classList.remove('show');}, 7000); &lt;3&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0console.log(await response.text());\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return false;\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0if (response.status &gt;= 400) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0console.log(\"Something when wrong\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0console.log(await response.text());\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0formError.textContent = \"Something went wrong while recording your contact.\"; &lt;4&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0formError.classList.toggle('show'); &lt;4&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0formError.classList.toggle('fade-out'); &lt;4&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setTimeout(function(){formError.classList.toggle('fade-out');formError.classList.toggle('show');}, 7000); &lt;4&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return false;\r\n\u00a0\u00a0\u00a0\u00a0}<\/pre>\n<pre class=\"nums:false lang:default decode:true\">&lt;1&gt; We assign our new spans to variables\r\n&lt;2&gt; If things went well, we reset the form's data, it shows to the user that it worked.\r\n&lt;3&gt; We first add a CSS class that shows the error message, than apply the fade-out CSS class, than call the timeout function. In 7000 ms, the fade-out and show CSS class will be removed, hiding the success message again.\r\n&lt;4&gt; We do the same thing when there is an error, using the formError HTML element instead.<\/pre>\n<p>Agora voc\u00ea pode testar o envio de um formul\u00e1rio novamente e ver a mensagem de sucesso ou de erro diferente, dependendo do que voc\u00ea decidiu fazer. Quando estiver satisfeito, voc\u00ea poder\u00e1 adicionar, confirmar e enviar esse c\u00f3digo.<\/p>\n<p><span style=\"font-weight: 400;\">Parab\u00e9ns, voc\u00ea chegou at\u00e9 o final deste guia! Voc\u00ea usou o git, o GitHub, o Netlify e o Couchbase Capella para implantar um formul\u00e1rio HTML na Web e certificou-se de que o conte\u00fado fosse armazenado em um banco de dados sempre que os usu\u00e1rios enviassem o formul\u00e1rio.<\/span><\/p>\n<h2>Pronto para mais?<\/h2>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Confira <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/developers\/\">Recursos para desenvolvedores do Couchbase<\/a>: aplicativos de amostra, c\u00f3digo e tutoriais.<\/li>\n<li>Participe de nossa <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/developers\/community\/\">Centro Comunit\u00e1rio<\/a> para usar o Discord, os f\u00f3runs e muito mais.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/developers\/community\/\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-14769 size-large\" style=\"border: 1px solid;\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/08\/image_2023-08-28_191205758-1024x865.png\" alt=\"\" width=\"900\" height=\"760\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/08\/image_2023-08-28_191205758-1024x865.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/08\/image_2023-08-28_191205758-300x253.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/08\/image_2023-08-28_191205758-768x649.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/08\/image_2023-08-28_191205758-1320x1115.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/08\/image_2023-08-28_191205758.png 1536w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>The Couchbase DevRel team has been working with the Bad Website Club on freeCodeCamp materials.\u00a0 freeCodeCamp is a non-profit organization that consists of an interactive learning web platform, an online community forum, chat rooms, online publications and local organizations that [&hellip;]<\/p>","protected":false},"author":49,"featured_media":14772,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1814,1815,2225,9327,2201],"tags":[9832,1500,1776],"ppma_author":[9023],"class_list":["post-14768","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-application-design","category-best-practices-and-tutorials","category-cloud","category-javascript","category-tools-sdks","tag-netlify","tag-tutorial","tag-web-application"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Build a Survey App with Netlify and Couchbase - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/building-a-survey-app-with-netlify-and-couchbase\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Build a Survey App with Netlify and Couchbase\" \/>\n<meta property=\"og:description\" content=\"The Couchbase DevRel team has been working with the Bad Website Club on freeCodeCamp materials.\u00a0 freeCodeCamp is a non-profit organization that consists of an interactive learning web platform, an online community forum, chat rooms, online publications and local organizations that [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/building-a-survey-app-with-netlify-and-couchbase\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2023-08-29T01:20:02+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-08-31T18:21:04+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/08\/image_2023-08-28_192155937-1024x513.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"513\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Laurent Doguin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ldoguin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"unstructured.io\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/\"},\"author\":{\"name\":\"Laurent Doguin\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e\"},\"headline\":\"Build a Survey App with Netlify and Couchbase\",\"datePublished\":\"2023-08-29T01:20:02+00:00\",\"dateModified\":\"2023-08-31T18:21:04+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/\"},\"wordCount\":2988,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/08\/image_2023-08-28_192155937.png\",\"keywords\":[\"netlify\",\"tutorial\",\"web application\"],\"articleSection\":[\"Application Design\",\"Best Practices and Tutorials\",\"Couchbase Capella\",\"JavaScript\",\"Tools &amp; SDKs\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/\",\"name\":\"Build a Survey App with Netlify and Couchbase - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/08\/image_2023-08-28_192155937.png\",\"datePublished\":\"2023-08-29T01:20:02+00:00\",\"dateModified\":\"2023-08-31T18:21:04+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/08\/image_2023-08-28_192155937.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/08\/image_2023-08-28_192155937.png\",\"width\":3732,\"height\":1871},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Build a Survey App with Netlify and Couchbase\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e\",\"name\":\"Laurent Doguin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/12929ce99397769f362b7a90d6b85071\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g\",\"caption\":\"Laurent Doguin\"},\"description\":\"Laurent is a nerdy metal head who lives in Paris. He mostly writes code in Java and structured text in AsciiDoc, and often talks about data, reactive programming and other buzzwordy stuff. He is also a former Developer Advocate for Clever Cloud and Nuxeo where he devoted his time and expertise to helping those communities grow bigger and stronger. He now runs Developer Relations at Couchbase.\",\"sameAs\":[\"https:\/\/x.com\/ldoguin\"],\"honorificPrefix\":\"Mr\",\"birthDate\":\"1985-06-07\",\"gender\":\"male\",\"award\":[\"Devoxx Champion\",\"Couchbase Legend\"],\"knowsAbout\":[\"Java\"],\"knowsLanguage\":[\"English\",\"French\"],\"jobTitle\":\"Director Developer Relation & Strategy\",\"worksFor\":\"Couchbase\",\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/laurent-doguin\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Build a Survey App with Netlify and Couchbase - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/pt\/building-a-survey-app-with-netlify-and-couchbase\/","og_locale":"pt_BR","og_type":"article","og_title":"Build a Survey App with Netlify and Couchbase","og_description":"The Couchbase DevRel team has been working with the Bad Website Club on freeCodeCamp materials.\u00a0 freeCodeCamp is a non-profit organization that consists of an interactive learning web platform, an online community forum, chat rooms, online publications and local organizations that [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/building-a-survey-app-with-netlify-and-couchbase\/","og_site_name":"The Couchbase Blog","article_published_time":"2023-08-29T01:20:02+00:00","article_modified_time":"2023-08-31T18:21:04+00:00","og_image":[{"width":1024,"height":513,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/08\/image_2023-08-28_192155937-1024x513.png","type":"image\/png"}],"author":"Laurent Doguin","twitter_card":"summary_large_image","twitter_creator":"@ldoguin","twitter_misc":{"Written by":"unstructured.io","Est. reading time":"18 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/"},"author":{"name":"Laurent Doguin","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e"},"headline":"Build a Survey App with Netlify and Couchbase","datePublished":"2023-08-29T01:20:02+00:00","dateModified":"2023-08-31T18:21:04+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/"},"wordCount":2988,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/08\/image_2023-08-28_192155937.png","keywords":["netlify","tutorial","web application"],"articleSection":["Application Design","Best Practices and Tutorials","Couchbase Capella","JavaScript","Tools &amp; SDKs"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/","url":"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/","name":"Build a Survey App with Netlify and Couchbase - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/08\/image_2023-08-28_192155937.png","datePublished":"2023-08-29T01:20:02+00:00","dateModified":"2023-08-31T18:21:04+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/08\/image_2023-08-28_192155937.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/08\/image_2023-08-28_192155937.png","width":3732,"height":1871},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/building-a-survey-app-with-netlify-and-couchbase\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Build a Survey App with Netlify and Couchbase"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e","name":"Laurent Doguin","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/12929ce99397769f362b7a90d6b85071","url":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","caption":"Laurent Doguin"},"description":"Laurent \u00e9 um nerd metaleiro que mora em Paris. Em sua maior parte, ele escreve c\u00f3digo em Java e texto estruturado em AsciiDoc, e frequentemente fala sobre dados, programa\u00e7\u00e3o reativa e outras coisas que est\u00e3o na moda. Ele tamb\u00e9m foi Developer Advocate do Clever Cloud e do Nuxeo, onde dedicou seu tempo e experi\u00eancia para ajudar essas comunidades a crescerem e se fortalecerem. Atualmente, ele dirige as Rela\u00e7\u00f5es com Desenvolvedores na Couchbase.","sameAs":["https:\/\/x.com\/ldoguin"],"honorificPrefix":"Mr","birthDate":"1985-06-07","gender":"male","award":["Devoxx Champion","Couchbase Legend"],"knowsAbout":["Java"],"knowsLanguage":["English","French"],"jobTitle":"Director Developer Relation & Strategy","worksFor":"Couchbase","url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/laurent-doguin\/"}]}},"authors":[{"term_id":9023,"user_id":49,"is_guest":0,"slug":"laurent-doguin","display_name":"Laurent Doguin","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","author_category":"","last_name":"Doguin","first_name":"Laurent","job_title":"","user_url":"","description":"Laurent \u00e9 um nerd metaleiro que mora em Paris. Em sua maior parte, ele escreve c\u00f3digo em Java e texto estruturado em AsciiDoc, e frequentemente fala sobre dados, programa\u00e7\u00e3o reativa e outras coisas que est\u00e3o na moda. Ele tamb\u00e9m foi Developer Advocate do Clever Cloud e do Nuxeo, onde dedicou seu tempo e experi\u00eancia para ajudar essas comunidades a crescerem e se fortalecerem. Atualmente, ele dirige as Rela\u00e7\u00f5es com Desenvolvedores na Couchbase."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/14768","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/49"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=14768"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/14768\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/14772"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=14768"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=14768"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=14768"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=14768"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}