<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Junior Martins</title>
    <description>The latest articles on DEV Community by Junior Martins (@juniormartinxo).</description>
    <link>https://dev.to/juniormartinxo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F783615%2Fd1c62781-4c65-4ab1-adad-9a60324a39f5.jpg</url>
      <title>DEV Community: Junior Martins</title>
      <link>https://dev.to/juniormartinxo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/juniormartinxo"/>
    <language>en</language>
    <item>
      <title>Iris: an offline visual assistant in Brazilian Portuguese powered by Gemma 4</title>
      <dc:creator>Junior Martins</dc:creator>
      <pubDate>Tue, 12 May 2026 21:30:24 +0000</pubDate>
      <link>https://dev.to/juniormartinxo/iris-an-offline-visual-assistant-in-brazilian-portuguese-powered-by-gemma-4-2652</link>
      <guid>https://dev.to/juniormartinxo/iris-an-offline-visual-assistant-in-brazilian-portuguese-powered-by-gemma-4-2652</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-gemma-2026-05-06"&gt;Gemma 4 Challenge: Build with Gemma 4&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Iris&lt;/strong&gt; is an Android visual assistant for blind and low-vision users.&lt;/li&gt;
&lt;li&gt;It describes what the camera sees, out loud, in &lt;strong&gt;Brazilian Portuguese&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 4 multimodal&lt;/strong&gt; runs &lt;strong&gt;100% on the phone&lt;/strong&gt; via LiteRT-LM — no cloud, no telemetry, no &lt;code&gt;INTERNET&lt;/code&gt; permission.&lt;/li&gt;
&lt;li&gt;Three intent-specific modes: Continuous, Question, Reading.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;Iris&lt;/strong&gt;, an offline Android visual assistant for blind and low-vision users.&lt;/p&gt;

&lt;p&gt;The interaction is intentionally simple: point the phone camera at something, tap the screen, and Iris speaks what it sees in Brazilian Portuguese.&lt;/p&gt;

&lt;p&gt;Iris has three modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Continuous Mode&lt;/strong&gt; describes the scene in front of the user.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Question Mode&lt;/strong&gt; lets the user ask a spoken question about the current camera image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reading Mode&lt;/strong&gt; reads visible text aloud, such as a label, medicine box, sign, or package.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A fourth control, &lt;strong&gt;Repeat&lt;/strong&gt;, replays the last description — useful for users who could not catch it all the first time.&lt;/p&gt;

&lt;p&gt;The core constraint was not only "can Gemma 4 understand the image?" — the real question was whether this could still be useful when the camera is looking at private, everyday scenes and the user may not have a reliable network connection.&lt;/p&gt;

&lt;p&gt;That led to the main technical decision: &lt;strong&gt;everything runs on the phone&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No server. No cloud API. No telemetry. No &lt;code&gt;INTERNET&lt;/code&gt; permission in the Android manifest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/cdug6i_HEJM"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The demo shows Iris running on a Galaxy S21 with airplane mode visible. The right side of the video is the actual phone screen; the left side explains what each mode is doing.&lt;/p&gt;

&lt;p&gt;The video is not meant to hide the on-device latency. On a Galaxy S21, the first spoken sentence arrives in roughly 25–30 seconds after the tap. The wait is part of the point: Gemma 4 is doing the multimodal work locally, on the phone, with no help from a server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;Repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/juniormartinxo/iris" rel="noopener noreferrer"&gt;https://github.com/juniormartinxo/iris&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project is a native Android app built with Kotlin, Jetpack Compose, CameraX, Android TTS/STT, and LiteRT-LM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This App Needed To Be Offline
&lt;/h2&gt;

&lt;p&gt;A visual assistant sees the user's world.&lt;/p&gt;

&lt;p&gt;That can mean a medicine label, a document on a desk, a room at home, a person nearby, a screen, or an object the user is trying to identify. For this kind of app, "send the image to a server" is not a neutral implementation detail. It changes the privacy model of the product.&lt;/p&gt;

&lt;p&gt;I wanted Iris to have a stronger boundary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;camera frames stay on the device;&lt;/li&gt;
&lt;li&gt;speech recognition uses Android's on-device recognizer;&lt;/li&gt;
&lt;li&gt;speech output uses Android Text-to-Speech;&lt;/li&gt;
&lt;li&gt;Gemma 4 runs through LiteRT-LM locally;&lt;/li&gt;
&lt;li&gt;the app does not request Internet access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Android manifest only asks for the permissions the app needs to see and hear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.CAMERA"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.RECORD_AUDIO"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no &lt;code&gt;android.permission.INTERNET&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That means the app cannot silently fall back to a network call unless a future version explicitly changes the permission model.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Gemma 4
&lt;/h2&gt;

&lt;p&gt;Iris uses &lt;strong&gt;Gemma 4 E2B&lt;/strong&gt; as the primary model, packaged as a &lt;code&gt;.litertlm&lt;/code&gt; bundle and loaded with LiteRT-LM on Android.&lt;/p&gt;

&lt;p&gt;I chose E2B because the target device is a phone, not a workstation. The challenge prompt asks builders to be intentional about model selection, and for this project the priority was clear: local multimodal inference with the smallest model that could still make the experience meaningful.&lt;/p&gt;

&lt;p&gt;The app can also look for an E4B bundle as a fallback, but the loading order prefers E2B:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;MODEL_CANDIDATES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"E2B"&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"gemma-4-E2B-it.litertlm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"E4B"&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"gemma-4-E4B-it.litertlm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the current demo, E2B is the right trade-off: it keeps the app viable on devices like the Galaxy S21 and A55 while still giving Iris native multimodal understanding.&lt;/p&gt;

&lt;p&gt;The app sends Gemma 4 one camera frame plus a mode-specific prompt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;in &lt;strong&gt;Continuous Mode&lt;/strong&gt;, the prompt asks for a short scene description focused on obstacles, relevant objects, visible text, and people;&lt;/li&gt;
&lt;li&gt;in &lt;strong&gt;Question Mode&lt;/strong&gt;, Android's on-device speech recognizer captures the user's question, then Gemma 4 answers using the current image;&lt;/li&gt;
&lt;li&gt;in &lt;strong&gt;Reading Mode&lt;/strong&gt;, the prompt asks Gemma 4 to read visible text from top to bottom and left to right.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All prompts ask for Brazilian Portuguese output because the product is designed for PT-BR users first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;The runtime path is deliberately small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CameraX preview
  -&amp;gt; capture current frame
  -&amp;gt; downsample image to a 512px longest edge
  -&amp;gt; run frame quality checks
  -&amp;gt; Gemma 4 E2B through LiteRT-LM
  -&amp;gt; sentence buffer
  -&amp;gt; Android Text-to-Speech
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a few details in that pipeline that matter.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Frame quality checks before inference
&lt;/h3&gt;

&lt;p&gt;On-device multimodal inference is expensive enough that Iris should not waste a run on a useless image.&lt;/p&gt;

&lt;p&gt;Before calling Gemma 4, the app calculates a small set of image quality signals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;brightness;&lt;/li&gt;
&lt;li&gt;luminance variance;&lt;/li&gt;
&lt;li&gt;a simple blur score.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the image is too dark, too bright, too empty, or too blurry, Iris speaks a direct instruction like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Imagem muito escura. Verifique a iluminação ou se há algo cobrindo a câmera."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is better than waiting through a slow inference only to get a weak answer.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Sentence streaming into TTS
&lt;/h3&gt;

&lt;p&gt;LiteRT-LM returns text chunks. Iris does not wait for the entire response before speaking.&lt;/p&gt;

&lt;p&gt;A small &lt;code&gt;SentenceBuffer&lt;/code&gt; collects chunks until it sees a sentence boundary, then sends each sentence to Android TTS. The user hears the first useful sentence as soon as possible, while the model can still finish the rest of the response.&lt;/p&gt;

&lt;p&gt;For accessibility, this is not just a polish detail. Silence during a long local inference can feel like the app froze. Iris speaks "Aguarde." as a progress beacon every 15 seconds while inference is still running. The moment the first sentence arrives from the model, the loading overlay disappears and the description starts streaming into the screen — one sentence at a time — so visual and audio feedback stay in sync.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Modes are prompt engineering exposed as UI
&lt;/h3&gt;

&lt;p&gt;I did not want one generic "describe" button to handle every situation.&lt;/p&gt;

&lt;p&gt;Blind and low-vision users often know what they need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"What is in front of me?"&lt;/li&gt;
&lt;li&gt;"Is there a silver object here?"&lt;/li&gt;
&lt;li&gt;"Read this medicine box."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The three modes let the UI choose the prompt shape before the model runs. This keeps the responses shorter, more predictable, and easier to listen to.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. TalkBack-aware behavior
&lt;/h3&gt;

&lt;p&gt;Iris is built around audio, but Android accessibility already has an audio layer: TalkBack.&lt;/p&gt;

&lt;p&gt;When TalkBack is enabled, Iris avoids speaking over UI announcements. When TalkBack is not enabled, Iris uses its own TTS announcements for mode changes, loading states, errors, and tutorial flow.&lt;/p&gt;

&lt;p&gt;Every primary control has a &lt;code&gt;contentDescription&lt;/code&gt;, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Continuous Mode;&lt;/li&gt;
&lt;li&gt;Question Mode;&lt;/li&gt;
&lt;li&gt;Reading Mode;&lt;/li&gt;
&lt;li&gt;Repeat.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This lets the same interface work for screen-reader users and for users who are not running TalkBack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance on the Galaxy S21
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Time / size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cold start to "Ready" (model load)&lt;/td&gt;
&lt;td&gt;~10–30 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tap → first spoken word&lt;/td&gt;
&lt;td&gt;~25–35 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tap → full response done&lt;/td&gt;
&lt;td&gt;~35–50 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory while idle (model loaded)&lt;/td&gt;
&lt;td&gt;~3 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;APK size (debug)&lt;/td&gt;
&lt;td&gt;~99 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model bundle (sideloaded &lt;code&gt;.litertlm&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;~2.59 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These are not best-in-class numbers. They are the cost of doing multimodal inference fully on-device on a 2021 phone. The UX is designed around making that wait legible, not invisible — that is what the progress beacon and the sentence streaming are for.&lt;/p&gt;

&lt;p&gt;Numbers above are approximate, taken on a single Galaxy S21 unit. They will vary by device, by ambient thermal state, and by how much memory the rest of the system is using.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Gemma 4 Unlocked
&lt;/h2&gt;

&lt;p&gt;The important thing about Gemma 4 here is not only that it can caption an image.&lt;/p&gt;

&lt;p&gt;It lets Iris treat visual assistance as a flexible language problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a scene can be summarized;&lt;/li&gt;
&lt;li&gt;a user question can be grounded in the image;&lt;/li&gt;
&lt;li&gt;visible text can be read in context;&lt;/li&gt;
&lt;li&gt;the output can be constrained to short, spoken PT-BR sentences.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without a multimodal model, this app would likely become a collection of separate systems: one detector, one OCR pipeline, one classifier, one rules engine, and a lot of glue code. That can be the right architecture for a mature product, but it is much heavier for a fast prototype.&lt;/p&gt;

&lt;p&gt;Gemma 4 made it possible to build one coherent loop:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;image + intent -&amp;gt; useful spoken answer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Was Hard
&lt;/h2&gt;

&lt;p&gt;The hardest part was not wiring the camera to the model. It was making the experience feel reliable enough for an audio-first user.&lt;/p&gt;

&lt;p&gt;Some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The app must tell the user when the model is still working.&lt;/li&gt;
&lt;li&gt;A second tap should cancel or replace the previous flow cleanly.&lt;/li&gt;
&lt;li&gt;If speech recognition is unavailable offline, the app should explain that instead of failing silently.&lt;/li&gt;
&lt;li&gt;If the camera points at a blank wall, the model should not invent a detailed scene.&lt;/li&gt;
&lt;li&gt;If the device is too hot, the app should refuse another expensive inference instead of making the phone worse.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some other details would have been invisible in a tech demo but mattered for a real app: guarding the camera tap area against overlay-based tap-jacking, capping the crash log file size so a failure loop cannot fill the disk, synchronizing access to the speech recognizer so it cannot be torn down mid-utterance. Each one came from imagining what a confused or panicked user would experience.&lt;/p&gt;

&lt;p&gt;Iris is still a prototype, but these details are the difference between a tech demo and something that starts to behave like a product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;The current version has real constraints.&lt;/p&gt;

&lt;p&gt;First, local inference on a Galaxy S21 can take a while. That is the cost of running a multimodal model offline on a phone-class device. The app is designed to keep the user informed during that wait, but latency is still the biggest UX limitation.&lt;/p&gt;

&lt;p&gt;Second, Iris is not a navigation or safety-critical tool. It can describe what the camera sees, but it should not be used as the only source of truth for crossing streets, avoiding hazards, or making medical decisions.&lt;/p&gt;

&lt;p&gt;Third, Reading Mode uses Gemma 4's multimodal ability rather than a dedicated OCR engine. That keeps the architecture simple and demonstrates what the model can do, but a production version might combine Gemma 4 with a specialized OCR pipeline for speed and fidelity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;The model is sideloaded because it is large. The app expects the LiteRT-LM bundle under the app's external files directory.&lt;/p&gt;

&lt;p&gt;Short version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew :app:assembleDebug

adb &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; app/build/outputs/apk/debug/iris-0.1.0-debug.apk

adb push gemma-4-E2B-it.litertlm &lt;span class="se"&gt;\&lt;/span&gt;
  /sdcard/Android/data/com.iris/files/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Model source:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://huggingface.co/litert-community/gemma-4-E2B-it-litert-lm" rel="noopener noreferrer"&gt;https://huggingface.co/litert-community/gemma-4-E2B-it-litert-lm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The README includes the full setup notes, including Android version, memory, storage, and offline PT-BR TTS/STT requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The next improvements I would make are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;test the same build across more Android devices;&lt;/li&gt;
&lt;li&gt;improve latency with better model/runtime configuration;&lt;/li&gt;
&lt;li&gt;add a more explicit first-run checklist for offline language packs;&lt;/li&gt;
&lt;li&gt;explore a hybrid Reading Mode that uses dedicated OCR when speed matters;&lt;/li&gt;
&lt;li&gt;keep the permission model strict: no Internet unless the product direction changes openly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Acknowledgments
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Google AI Edge&lt;/strong&gt; team for LiteRT-LM, which makes running Gemma 4 on Android tractable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;litert-community&lt;/code&gt;&lt;/strong&gt; on Hugging Face for the &lt;code&gt;.litertlm&lt;/code&gt; model bundles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anthropic Claude Code&lt;/strong&gt; was used as a pair-programming assistant during development of the Android code, the UX logic, and parts of this article.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;Iris is small, but it represents the kind of app I want to see more often: local-first, accessibility-first, and built for a real language community instead of assuming English by default.&lt;/p&gt;

&lt;p&gt;Gemma 4 made the prototype possible because it brought multimodal understanding close enough to the device. LiteRT-LM made it possible to run that loop inside Android.&lt;/p&gt;

&lt;p&gt;The result is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The camera sees. Gemma 4 understands. Iris speaks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And it does that without sending the image anywhere.&lt;/p&gt;

</description>
      <category>gemmachallenge</category>
      <category>devchallenge</category>
      <category>gemma</category>
      <category>android</category>
    </item>
    <item>
      <title>Como habilitar a assinatura automática de commits do Git com GnuPG (GPG) no Windows</title>
      <dc:creator>Junior Martins</dc:creator>
      <pubDate>Sun, 02 Apr 2023 13:45:53 +0000</pubDate>
      <link>https://dev.to/juniormartinxo/como-habilitar-a-assinatura-automatica-de-commits-do-git-com-gnupg-gpg-no-windows-26o9</link>
      <guid>https://dev.to/juniormartinxo/como-habilitar-a-assinatura-automatica-de-commits-do-git-com-gnupg-gpg-no-windows-26o9</guid>
      <description>&lt;p&gt;&lt;em&gt;Este é um guia para habilitar &lt;code&gt;git commits&lt;/code&gt; com assinatura &lt;code&gt;GPG&lt;/code&gt; no GitHub.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"O GnuPG é um programa de software de criptografia híbrida porque usa uma combinação de criptografia de chave simétrica convencional por questões de velocidade e criptografia de chave pública para facilitar a troca segura de chaves, geralmente usando a chave pública do destinatário para criptografar uma chave de sessão que é usada apenas uma vez. Este modo de operação faz parte do padrão OpenPGP e faz parte do PGP desde sua primeira versão."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pt.wikipedia.org/wiki/GNU_Privacy_Guard"&gt;Wikipédia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  1) Instale &lt;code&gt;Gpg4win&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Gpg4win pode ser baixado em &lt;a href="//www.gpg4win.org"&gt;www.gpg4win.org&lt;/a&gt;{:target="_blank"}&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;Gpg4win&lt;/code&gt; é um pacote do &lt;code&gt;GnuPG v2&lt;/code&gt;, que contem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Kleopatra&lt;/code&gt;, que é um gerenciador de certificados;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GNU Privacy Assitant (GPA)&lt;/code&gt;, que é uma &lt;code&gt;GUI&lt;/code&gt; que usa &lt;code&gt;GTK + GpgOL&lt;/code&gt; e &lt;code&gt;GpgEX&lt;/code&gt;, que são respectivamente uma extensão para &lt;code&gt;Outlook&lt;/code&gt; e &lt;code&gt;Windows Shell&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Como o foco deste tutorial não é demonstrar a utilização no Outlook, não iremos instalar o &lt;code&gt;GpgOL&lt;/code&gt;, portanto, na janela de &lt;em&gt;"Escolha de Componentes"&lt;/em&gt;, deixe conforme a imagem abaixo:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Knj_h4yS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080151-42e78738-ce4f-4502-a2a0-0700cd8ace2d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Knj_h4yS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080151-42e78738-ce4f-4502-a2a0-0700cd8ace2d.png" alt="image" width="496" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aperte o botão &lt;code&gt;seguinte&lt;/code&gt; e depois selecione o diretório onde os arquivos do programa &lt;code&gt;Gp4win&lt;/code&gt; ficarão (&lt;em&gt;você irá precisar desta informação mais pra frente&lt;/em&gt;), feito isto clique em &lt;code&gt;instalar&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  2) Crie uma nova &lt;code&gt;key pair&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Após a instalação do &lt;code&gt;Gp4win&lt;/code&gt;, abra o programa &lt;code&gt;Kleopatra&lt;/code&gt;:&lt;br&gt;
Na janela inicial vá ao menu &lt;code&gt;File &amp;gt; New Key Pair...&lt;/code&gt;, abrirá uma nova janela, nela clique no botão &lt;code&gt;Create a personal OpenPGP key pair&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xW0gOkJR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080282-f9d32a95-b621-4417-be86-bea8f82706e6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xW0gOkJR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080282-f9d32a95-b621-4417-be86-bea8f82706e6.png" alt="image" width="500" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uma nova janela solicitando algumas informações será aberta, agora basta preencher os campos com os seus dados &lt;code&gt;Nome&lt;/code&gt; e &lt;code&gt;Email&lt;/code&gt; e marcar a caixa &lt;code&gt;Protect the generated key with a passphrase&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YwoEb_pG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080360-2e1b6c0c-df8a-44f9-a063-0bcf010b3072.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YwoEb_pG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080360-2e1b6c0c-df8a-44f9-a063-0bcf010b3072.png" alt="image" width="500" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ainda na mesma janela clique em &lt;code&gt;Advanced Settings...&lt;/code&gt;, na nova janela que abrir, selecione &lt;code&gt;RSA&lt;/code&gt;, marque &lt;code&gt;+ RSA-&lt;/code&gt;, e altere os valores dos selects para &lt;code&gt;4,096 bits&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;No campo &lt;code&gt;Valid until:&lt;/code&gt; escolha uma data limite para a validade da chave que será criada, no exemplo deixei a data de &lt;code&gt;03/09/2023&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lYZeKEU6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080388-22ecd5c0-b0dc-42ff-b1aa-45b259a55b4f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lYZeKEU6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080388-22ecd5c0-b0dc-42ff-b1aa-45b259a55b4f.png" alt="image" width="377" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clique em &lt;code&gt;Ok&lt;/code&gt; e depois em &lt;code&gt;Create&lt;/code&gt;, feito este procedimento abrirá uma nova janela para que você digite uma senha:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P4MyO9im--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080409-0645f276-b30b-436b-abd7-2f3fc76271fa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4MyO9im--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080409-0645f276-b30b-436b-abd7-2f3fc76271fa.png" alt="image" width="290" height="164"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A senha deve ter no mínimo &lt;code&gt;08 (oito) dígitos&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Após digitar a senha clique em &lt;code&gt;OK&lt;/code&gt; e aguarde até que o sistema gere sua &lt;code&gt;Key Pair&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Realizado o procedimento anterior e dando tudo certo, abrirá uma nova janela com a mensagem "&lt;em&gt;Key Pair Succesfully Created&lt;/em&gt;" contendo algumas informações sobre a nova chave criada, conforme a imagem abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KFUnLQn1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080453-87940d9d-6a58-4d72-b1b5-b3d7caec2874.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KFUnLQn1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080453-87940d9d-6a58-4d72-b1b5-b3d7caec2874.png" alt="image" width="500" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gerada a &lt;code&gt;Kei Pair&lt;/code&gt;, clique em &lt;code&gt;Finish&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  3) Copiando a chave GPG criada
&lt;/h3&gt;

&lt;p&gt;Se tudo deu certo até aqui você perceberá que na janela principal do &lt;code&gt;Kleopatra&lt;/code&gt; vai estar aparecendo as informações básicas da sua nova chave, algo parecido com a imagem abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tcUHCZHs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080477-c84f09be-3b6a-4f66-9a48-5f03c4fe7800.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tcUHCZHs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080477-c84f09be-3b6a-4f66-9a48-5f03c4fe7800.png" alt="image" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clique duas vezes na linha que possui a nova chave gerada para abrir a janela &lt;code&gt;Export&lt;/code&gt;, que permitirá que exportemos a chave criada. Com a janela &lt;code&gt;Export&lt;/code&gt; aberta, clique em &lt;code&gt;Export...&lt;/code&gt;. Abrirá uma nova janela &lt;code&gt;Export - Kleopatra&lt;/code&gt;, selecione todo o texto e copie &lt;code&gt;Ctrl+C&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ahEN2sqj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080620-e74494d8-1218-4a9f-ad56-8a41e425cac5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ahEN2sqj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080620-e74494d8-1218-4a9f-ad56-8a41e425cac5.png" alt="image" width="602" height="828"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após copiar, clique em &lt;code&gt;close&lt;/code&gt; e depois em &lt;code&gt;close&lt;/code&gt; novamente.&lt;/p&gt;


&lt;h3&gt;
  
  
  4) Inserindo a chave GPG no Github
&lt;/h3&gt;

&lt;p&gt;De posse da chave copiada no "item 3" deste tutorial, vá ao &lt;code&gt;GitHub&lt;/code&gt; e navegue pelo menu em &lt;code&gt;Settings &amp;gt; SHH and GPG keys&lt;/code&gt; e na janela que abrir procure pelo botão &lt;code&gt;New GPG Key&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2lMI5g0r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080663-aa5219a0-de71-4e85-a08d-bc29a53d152d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2lMI5g0r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080663-aa5219a0-de71-4e85-a08d-bc29a53d152d.png" alt="image" width="750" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicando em &lt;code&gt;New GPG Key&lt;/code&gt;, abrirá uma nova janela com o campo &lt;code&gt;GPG keys/ Add new&lt;/code&gt;, neste campo cole todo o texto que você copiou no "item 3" deste tutorial, deixando mais ou menos assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ti8u1f7h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080694-b9c250d8-3d55-4c4a-b3f7-fcc4d1f26037.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ti8u1f7h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080694-b9c250d8-3d55-4c4a-b3f7-fcc4d1f26037.png" alt="image" width="767" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Colado o texto, cliquem em &lt;code&gt;Add GPG Key&lt;/code&gt;. Você será redirecionado para a página &lt;code&gt;SSH and GPG keys&lt;/code&gt;, que agora conterá as informações básicas da sua nova chave GPG criada, como na imagem abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tl7gFHQP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080800-1cc893f3-8bef-4838-b3d5-ade59c82ea91.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tl7gFHQP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080800-1cc893f3-8bef-4838-b3d5-ade59c82ea91.png" alt="image" width="736" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡&lt;strong&gt;Atenção&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Na imagem acima aparace a mensagem &lt;code&gt;Unverified&lt;/code&gt; ao lado do e-mail inserido. Isto é um alerta indicando que o e-mail não está  vinculado à sua conta do GitHub, portanto, se você inserir o e-mail correto vinculado à sua conta, a mensagem de não aparecerá&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h3&gt;
  
  
  5) Configurando o Git para realizar commits verificados
&lt;/h3&gt;

&lt;p&gt;Abra o terminal e digite o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; commit.gpgsign &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Volte na página &lt;code&gt;SSH an GPG keys&lt;/code&gt; do &lt;code&gt;GitHub&lt;/code&gt; e copie o valor de &lt;code&gt;Key ID&lt;/code&gt;, o que está em azul na imagem abaixo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;O valor da sua Key ID será diferente do da imagem&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z0jSg86Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080953-e1f97f0a-a55a-4e3a-b621-b1c2235f1bff.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z0jSg86Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132080953-e1f97f0a-a55a-4e3a-b621-b1c2235f1bff.png" alt="image" width="736" height="123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copiado o valor, volte ao terminal e digite o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.signingkey MEU_KEY_ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Substitua MEU_KEY_ID pelo valor copiado na página "SSH an GPG keys"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Feito, agora digite o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; gpg.program &lt;span class="s1"&gt;'Disco:/caminho/do/GnuPG/bin/gpg.exe`
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  🏷️&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; gpg.program &lt;span class="s1"&gt;'C:/programs/GnuPG/bin/gpg.exe`
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Atenção&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Use o caminho completo utilizando &lt;code&gt;/&lt;/code&gt; e não &lt;code&gt;\&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  6) Testando o comando
&lt;/h3&gt;

&lt;p&gt;Se deu tudo certo a partir de agora você será capaz de realizar commits verificados para sua conta no GitHub, para isso, faça um commit utilizando a flag &lt;code&gt;-S&lt;/code&gt;, assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'Commit verificado'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao clicar em &lt;code&gt;enter&lt;/code&gt; abrirá uma nova janela solicitando a senha que foi criada no momento da geração da chave no &lt;code&gt;Kleopatra&lt;/code&gt;. Digite a senha correta e tecle &lt;code&gt;enter&lt;/code&gt;, que o commit será realizado.&lt;/p&gt;

&lt;p&gt;Para finalizar, depois do commit, dê um &lt;code&gt;push&lt;/code&gt; e seja feliz 😁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seus commits aparecerão no histórico com uma tag &lt;code&gt;verified&lt;/code&gt; ao lado, conforme a imagem abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AFCAcmSM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132081292-26b2c7b6-82f0-4a63-a311-9446bc888a98.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AFCAcmSM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/4163340/132081292-26b2c7b6-82f0-4a63-a311-9446bc888a98.png" alt="image" width="282" height="224"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  7) Habilitando no WSL2
&lt;/h3&gt;

&lt;p&gt;Para habilitar a assinatura automática de commits do Git com GnuPG (GPG) no Windows Subsystem for Linux (WSL), siga os passos abaixo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;7.1 - Instale o GnuPG no WSL: Abra um terminal do WSL e execute o seguinte comando para instalar o GnuPG:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt install gnupg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso irá instalar o GnuPG no seu ambiente WSL.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;7.2 - Gere suas chaves GPG: Para assinar commits automaticamente, você precisa ter uma chave GPG. Se você já possui uma chave GPG, você pode pular esta etapa. Caso contrário, você pode gerar uma nova chave GPG usando o seguinte comando:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--gen-key&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Siga as instruções do GnuPG para gerar uma nova chave GPG. Você precisará definir uma senha para sua chave GPG durante o processo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;7.3 - Configure o Git para usar a chave GPG: Após gerar sua chave GPG, você precisa configurar o Git para usá-la. Para fazer isso, execute os seguintes comandos no terminal do WSL:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.signingkey &amp;lt;sua_chave_gpg&amp;gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; commit.gpgsign &lt;span class="nb"&gt;true
&lt;/span&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; gpg.program gpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Substitua &lt;code&gt;&amp;lt;sua_chave_gpg&amp;gt;&lt;/code&gt; pelo ID da chave GPG que você gerou na etapa anterior.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;7.4 - Exporte sua chave GPG pública: No terminal do WSL, você pode exportar sua chave GPG pública usando o seguinte comando:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--armor&lt;/span&gt; &lt;span class="nt"&gt;--export&lt;/span&gt; &amp;lt;seu_ID_de_chave&amp;gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; chave_gpg_publica.asc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;7.5 - Substitua &lt;code&gt;&amp;lt;seu_ID_de_chave&amp;gt;&lt;/code&gt; pelo ID da sua chave GPG que você deseja adicionar ao GitHub. Isso irá criar um arquivo com extensão ".asc" que contém a sua chave GPG pública.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;7.6 - Importe sua chave GPG no WSL: Você também precisa importar sua chave GPG no WSL para que o Git possa encontrar e usar sua chave para assinar os commits automaticamente. Para importar a chave, você pode usar o seguinte comando:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--import&lt;/span&gt; &amp;lt;caminho_para_sua_chave_gpg&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Exemplo&lt;br&gt;
gpg --import chave_gpg_publica.asc&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;7.7 - Substitua &lt;code&gt;&amp;lt;caminho_para_sua_chave_gpg&amp;gt;&lt;/code&gt; pelo caminho completo para o arquivo da chave GPG que você exportou ou recebeu de outra fonte.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;7.8 - Configure sua variável de ambiente GPG_TTY: Para que a assinatura automática de commits funcione corretamente no WSL, você precisa configurar a variável de ambiente GPG_TTY. Você pode fazer isso adicionando o seguinte comando ao seu arquivo de perfil do shell (por exemplo, ~/.bashrc ou ~/.zshrc):&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GPG_TTY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;tty&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso permitirá que o GnuPG encontre o terminal correto para exibir os prompts de senha quando necessário.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adicionando a chave do WSL ao Github
&lt;/h3&gt;

&lt;p&gt;Para adicionar sua chave GPG ao GitHub, você pode seguir os passos abaixo:&lt;br&gt;
Copie o conteúdo do arquivo de chave pública: Abra o arquivo de chave pública gerado (chave_gpg_publica.asc) em um editor de texto ou em um visualizador de arquivos e copie todo o conteúdo do arquivo.&lt;br&gt;
Copiada a chave siga o procedimento listado no passo &lt;code&gt;4) Inserindo a chave GPG no Github&lt;/code&gt; deste tutorial.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Remix :: CRUD com Supabase - Parte 06 - Testando a inserção de novos registros</title>
      <dc:creator>Junior Martins</dc:creator>
      <pubDate>Wed, 18 May 2022 20:32:41 +0000</pubDate>
      <link>https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-06-testando-a-insercao-de-novos-registros-2m64</link>
      <guid>https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-06-testando-a-insercao-de-novos-registros-2m64</guid>
      <description>&lt;p&gt;Nesta parte iremos testar se o nosso formulário está funcionando.&lt;/p&gt;

&lt;p&gt;Vamos editar novamente o arquivo &lt;code&gt;index.tsx&lt;/code&gt; e colocar o nosso menu que irá para área de postagens, onde iremos visualizar e inserir novas postagens&lt;/p&gt;

&lt;h3&gt;
  
  
  Re-editando o arquivo &lt;code&gt;index.tsx&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Abra seu arquivo &lt;code&gt;routes/index.tsx&lt;/code&gt;, apague os &lt;code&gt;imports&lt;/code&gt; e importe apenas o componente &lt;code&gt;Link&lt;/code&gt; do Remix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;remix&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora edite o componente &lt;code&gt;Index&lt;/code&gt;, deixando-o assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system-ui, sans-serif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lineHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Blog&lt;/span&gt; &lt;span class="nx"&gt;Remix&lt;/span&gt; &lt;span class="nx"&gt;com&lt;/span&gt; &lt;span class="nx"&gt;Supabase&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;
        &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
          &lt;span class="na"&gt;listStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt;
            &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
              &lt;span class="na"&gt;textDecoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ef62df&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;14px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nx"&gt;Visualizar&lt;/span&gt; &lt;span class="nx"&gt;Posts&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por último, vamos adicionar um componente &lt;code&gt;ErrorBoundary&lt;/code&gt; para "capturar" os erros na &lt;code&gt;Index&lt;/code&gt; de forma que não quebre o resto da aplicação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error-container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;😱&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;pre&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;❗&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/pre&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Testando a aplicação
&lt;/h3&gt;

&lt;p&gt;Finalmente estamos prontos para testar a nossa aplicação, para isto rode &lt;code&gt;npm run dev&lt;/code&gt; e se tudo deu certo você verá no navegador algo parecido com a imagem abaixo:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0yoo4w1wb91xkyx6hsxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0yoo4w1wb91xkyx6hsxz.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
 Clique no link &lt;code&gt;Visualizar Posts&lt;/code&gt; e você será direcionado para a página de visulização, que também será nossa página de inseração de novos posts.&lt;/p&gt;

&lt;p&gt;A página que será aberta deve ser algo parecido com a imagem abaixo:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1jzxaq8rte5w9biimruu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1jzxaq8rte5w9biimruu.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Clique no botão &lt;code&gt;Novo&lt;/code&gt; e repare que o formulário abrirá logo acima da visualização dos posts e isto se deve a mágica do componente &lt;code&gt;&amp;lt;Outlet/&amp;gt;&lt;/code&gt; que inserimos na parte 05 enquanto estávamos editando o componente &lt;code&gt;Posts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Clique em novo, preencha todos os dados e depois clique em &lt;code&gt;enviar&lt;/code&gt;. Se tudo deu certo até aqui, um novo post aparecerá abaixo dos botões &lt;code&gt;Home&lt;/code&gt; e &lt;code&gt;Novo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Com isto finalizamos esta primeira parte do tutorial, na parte 07 instalaremos a lib &lt;a href="https://chakra-ui.com/" rel="noopener noreferrer"&gt;https://chakra-ui.com/&lt;/a&gt; para melhorar a aparência da nossa aplicação. Te vejo lá! 😉&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Remix :: CRUD com Supabase - Parte 05 - Trabalhando com formulário</title>
      <dc:creator>Junior Martins</dc:creator>
      <pubDate>Wed, 18 May 2022 20:32:25 +0000</pubDate>
      <link>https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-05-trabalhando-com-formulario-5g14</link>
      <guid>https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-05-trabalhando-com-formulario-5g14</guid>
      <description>&lt;p&gt;Nesta parte veremos o quanto é fácil trabalhar com formulários no Remix, iremos melhorar nossa estrutura de arquivos, colocando as coisas nos lugares certos para evitar código duplicado e permitir assim o reaproveitamento na nossa aplicação.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎲 Criando o modelo
&lt;/h3&gt;

&lt;p&gt;Nas partes anteriores deste tutorial nós criamos a &lt;code&gt;PostModel&lt;/code&gt; nos arquivos onde ele era necessário, mas agora iremos deixá-lo em lugar onde "quem precisar" na aplicação possa usá-lo, portanto, crie o arquivo &lt;code&gt;posts.model.ts&lt;/code&gt; dentro da pasta &lt;code&gt;app/models/&lt;/code&gt;, de forma que ele fique assim: &lt;code&gt;app/models/posts.model.ts&lt;/code&gt;. Edite-o e deixe desta forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PostsModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="nx"&gt;post_uuid&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;post_author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;post_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;post_situation&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;post_created_at&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Criando a API
&lt;/h3&gt;

&lt;p&gt;Criado o modelo, podemos agora trabalhar com a API, que armazenará todas as ações que permitirão executar nosso CRUD, para isto, crie o arquivo &lt;code&gt;supabase-api.ts&lt;/code&gt; dentro do diretório &lt;code&gt;app/api/&lt;/code&gt;, de forma que fique assim: &lt;code&gt;app/api/supabase-api.ts&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Edite o arquivo &lt;code&gt;supabase-api.ts&lt;/code&gt; e import o &lt;code&gt;PostsModels&lt;/code&gt; e o cliente &lt;code&gt;supabase&lt;/code&gt;, deixando-o assim:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PostsModel&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;~/models/posts.model&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;~/utils/supabase-client.server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Ainda no &lt;code&gt;supabase-api.ts&lt;/code&gt;. crie a função &lt;code&gt;getPosts&lt;/code&gt;, que ficará encarregada de realizar um &lt;code&gt;select&lt;/code&gt; no Supabase para nós.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PostsModel&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post_id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ascending&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Agora criaremos a função &lt;code&gt;addPost&lt;/code&gt;, que ficará responsável por adicionar um registro novo.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;post_author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;post_text&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;PostsModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PostsModel&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;post_author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post_author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;post_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Por fim, exporte as duas funcões:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addPost&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Criando a rota &lt;code&gt;posts&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Crie dentro da pasta &lt;code&gt;routes&lt;/code&gt; um arquivo com nome &lt;code&gt;posts.tsx&lt;/code&gt; e dentro dele faça os seguintes imports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LoaderFunction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Outlet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useLoaderData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;remix&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;~/api/supabase-api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PostsModel&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;~/models/posts.model&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Link&lt;/code&gt; para criarmos o link que irá chamará o formulário para iserir um novo registro;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;LoaderFunction&lt;/code&gt; para tiparmos o método &lt;code&gt;loader&lt;/code&gt; que ficará responsável por chamar a função &lt;code&gt;getPosts&lt;/code&gt;, que carrega os registros do banco de dados;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useLoaderData&lt;/code&gt; permite façamos o uso dos dados carregados pelo &lt;code&gt;loader&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Outlet&lt;/code&gt;, este componente é um wrapper em torno do Outlet do React Router com a capacidade de passar o estado da interface do usuário para rotas aninhadas. Ou seja, com ele será possível carregar a rota filha que conterá o fomulário dentro da rota pai &lt;code&gt;posts.tsx&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getPosts&lt;/code&gt; é a função que carrega os registros do banco de dados; e&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;postModels&lt;/code&gt; é o &lt;code&gt;type model&lt;/code&gt; dos dados que virão do banco de dados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feito as importações criaremos o método &lt;code&gt;loader&lt;/code&gt; para chamar a &lt;code&gt;getPosts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LoaderFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora iremos criar nosso componente &lt;code&gt;Posts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Posts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLoaderData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PostsModel&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system-ui, sans-serif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lineHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Blog&lt;/span&gt; &lt;span class="nx"&gt;Remix&lt;/span&gt; &lt;span class="nx"&gt;com&lt;/span&gt; &lt;span class="nx"&gt;Supabase&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;
        &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
          &lt;span class="na"&gt;listStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;
            &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
              &lt;span class="na"&gt;textDecoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ef62df&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;14px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nx"&gt;Home&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt;
            &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
              &lt;span class="na"&gt;textDecoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#62efd0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#0d6443&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;14px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nx"&gt;Novo&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Outlet&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;listStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post_uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;small&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post_author&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/small&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;blockquote&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post_text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/blockquote&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="p"&gt;))}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E, por fim, chamaremos a função &lt;code&gt;ErrorBoundary&lt;/code&gt; do Remix, a qual permite que os erros sejam capturados dentro da rota que foi chamada, evitando assim que toda a aplicaçãose quebre:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error-container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;😱&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;pre&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;❗&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/pre&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Criando a página do fomulário
&lt;/h3&gt;

&lt;p&gt;Criado a página de listagem dos posts, iremos criar a página que conterá o fomulário que permitirá que a gente insira novos registros, para isto crie a pasta &lt;code&gt;posts&lt;/code&gt; dentro de &lt;code&gt;routes&lt;/code&gt;, de forma que fique &lt;code&gt;routes/posts&lt;/code&gt;. Dentro da pasta &lt;code&gt;posts&lt;/code&gt; crie o arquivo &lt;code&gt;new.tsx&lt;/code&gt; e faça as seguintes imports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ActionFunction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;redirect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;remix&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;~/utils/supabase-client.server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ActionFunction&lt;/code&gt; para tiparmos o método do Remix chamado &lt;code&gt;action&lt;/code&gt; que é reponsável por "capturar" as variáveis enviadas pelo fomulário. Na verdade &lt;code&gt;action&lt;/code&gt; pega todas varáveis de qualquer &lt;code&gt;request&lt;/code&gt; na rota onde ele está.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;redirect&lt;/code&gt; permite que a rota seja redirecionada&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;supabase&lt;/code&gt; é o nosso cliente do Supabase&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feito os &lt;code&gt;imports&lt;/code&gt;, chamaremos o método &lt;code&gt;action&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ActionFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromEntries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora criaremos o componente &lt;code&gt;NewPost&lt;/code&gt; que conterá nosso formulário:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;NewPost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system-ui, sans-serif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lineHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Novo&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;
        &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
          &lt;span class="na"&gt;listStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="nx"&gt;htmlFor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Título&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/label&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;br&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post_title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="nx"&gt;htmlFor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Autor&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/label&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;br&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post_author&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="nx"&gt;htmlFor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Texto&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/label&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;br&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;textarea&lt;/span&gt;
            &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post_text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post_text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="nx"&gt;cols&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/textarea&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;
            &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
              &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#62a4ef&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;lineHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;14px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pointer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nx"&gt;Enviar&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt;
            &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
              &lt;span class="na"&gt;marginLeft&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;textDecoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ef62df&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;14px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nx"&gt;Cancelar&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;br&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isto finalizamos o formulário e na parte 06 iremos criar nosso primeiro post através do formulário criado. Te espero lá! 😉&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Remix :: CRUD com Supabase - Parte 04 - Carregando e inserindo novos registros</title>
      <dc:creator>Junior Martins</dc:creator>
      <pubDate>Wed, 18 May 2022 20:31:27 +0000</pubDate>
      <link>https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-04-carregando-e-inserindo-novos-registros-2nic</link>
      <guid>https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-04-carregando-e-inserindo-novos-registros-2nic</guid>
      <description>&lt;p&gt;Nesta parte do tutorial verificaremos se a nossa comunicação com API do Supabase está funcionando corretamente e criaremos uma rota temporária que permitirá criar novos registros para testarmos as requisições.&lt;/p&gt;

&lt;h3&gt;
  
  
  Editando o arquivo &lt;code&gt;app/index.tsx&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Neste primeiro momento iremos verificar se a nossa conexão com o Supase está funcionando e para isto editaremos o arquivo &lt;code&gt;routes/index.tsx&lt;/code&gt; responsável por chamar a rota &lt;code&gt;index&lt;/code&gt; da nossa aplicação.&lt;/p&gt;

&lt;p&gt;1) Importe &lt;code&gt;LoaderFunction&lt;/code&gt; e &lt;code&gt;useLoaderData&lt;/code&gt; do Remix&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LoaderFunction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useLoaderData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;remix&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  O que é o método &lt;code&gt;loader: LoaderFunction&lt;/code&gt;?
&lt;/h5&gt;

&lt;p&gt;O &lt;code&gt;loader&lt;/code&gt; é uma função executada em server-side e é ela que usamos no Remix para obter dados externos, portanto a usaremos para obter os registros que virão do banco de dados.&lt;/p&gt;

&lt;h5&gt;
  
  
  Que é o hook &lt;code&gt;useLoaderData&lt;/code&gt;?
&lt;/h5&gt;

&lt;p&gt;O &lt;code&gt;useLoaderData&lt;/code&gt; é um hook provido pelo próprio Remix para que se possa ter acesso ao que é exportado pelo &lt;code&gt;loader&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2) Importe também o cliente do Supabase&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;~/utils/supabase-client.server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Crie o tipo &lt;code&gt;PostsModel&lt;/code&gt;, que além de tipar as nossas variáveis, vai nos ajudar muito no intelisense do VSCode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PostsModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;post_uuid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;post_author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;post_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;post_situation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;post_created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Agora, iremos dar um &lt;code&gt;select&lt;/code&gt; no Supabase para carregar as informações dos registros no &lt;code&gt;loader&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LoaderFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PostsModel&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post_id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ascending&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5) Deixe o componente &lt;code&gt;Index&lt;/code&gt; desta forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLoaderData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PostsModel&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system-ui, sans-serif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lineHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Blog&lt;/span&gt; &lt;span class="nx"&gt;Remix&lt;/span&gt; &lt;span class="nx"&gt;com&lt;/span&gt; &lt;span class="nx"&gt;Supabase&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/insert&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Inserir&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;listStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post_uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;small&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post_author&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/small&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;blockquote&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post_text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/blockquote&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;))}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para ver se tudo deu certo, rode o comando &lt;code&gt;npm run dev&lt;/code&gt; e você perceberá que irá aparecer apenas o título &lt;code&gt;Blog Remix com Supabase&lt;/code&gt;, pois não há nenhum registro inserido na base de dados.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Repare que foi criado um link &lt;code&gt;insert&lt;/code&gt; logo abaixo do título &lt;code&gt;Blog Remix com Supabase&lt;/code&gt;, se clicarmos nele agora seremos direcionados para uma página que não existe ainda e, inevitavelmente, receberemos um erro &lt;code&gt;404&lt;/code&gt;, mas isto será resolvido nos próximos passos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Criando a Rota temporária &lt;code&gt;insert&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Para testar e ver se a nossa comunicação com Supabase está realmente funcionando e se nosso &lt;code&gt;loader&lt;/code&gt; está trazendo as informações dos registros, faremos antes um &lt;code&gt;insert&lt;/code&gt; para escrever alguns registros no Supabase, que poderão ser apagados posteriormente, então, mãos a obra.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Aditivo:&lt;/strong&gt; &lt;em&gt;Nesta parte muito código será duplicado, mas não se preocupe, por enquanto faremos funcionar pra depois deixar mais limpo.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;1) Crie dentro da pasta &lt;code&gt;routes&lt;/code&gt; um arquivo com o nome &lt;code&gt;insert.tsx&lt;/code&gt; e faça os mesmos imports que fizemos em &lt;code&gt;index&lt;/code&gt;, ou seja:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LoaderFunction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useLoaderData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;remix&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;~/utils/supabase-client.server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Da mesma forma que na &lt;code&gt;index&lt;/code&gt;, crie o type &lt;code&gt;PostsModel&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PostsModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;post_uuid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;post_author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;post_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;post_situation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;post_created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Chame o método &lt;code&gt;loader&lt;/code&gt;, mas agora dando um &lt;code&gt;insert&lt;/code&gt; no Supabase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LoaderFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;post_author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Junior Martins&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;O título da sua aplicação&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;post_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Uma coisa é certa: ninguém sai vivo dessa vida.. Por que "tudo junto" se escreve separado e "separado" se escreve tudo junto?. Se tamanho fosse documento o elefante era dono do circo.. Não concordo nem discordo, muito pelo contrário. Em rio de piranhas, jacaré nada de costas. Um é pouco, dois é bom e três é ímpar. Um é pouco, dois é bom e três é ímpar. O sonho não acabou. E ainda temos pão doce, maria-mole e queijadinha. Uma coisa é uma coisa, outra coisa é outra coisa.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Aditivo:&lt;/strong&gt; &lt;em&gt;Você pode alterar o valor de &lt;code&gt;post_author&lt;/code&gt;, &lt;code&gt;post_title&lt;/code&gt; e &lt;code&gt;post_text&lt;/code&gt; dentro do método &lt;code&gt;loader&lt;/code&gt; para diferenciar os registros.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;4) Crie o componente &lt;code&gt;Insert&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Insert&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLoaderData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PostsModel&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Novo&lt;/span&gt; &lt;span class="nx"&gt;registro&lt;/span&gt; &lt;span class="nx"&gt;inserido&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system-ui, sans-serif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lineHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;small&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post_author&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/small&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;blockquote&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post_text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/blockquote&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para finalizar, inicie sua aplicação e clique no link &lt;code&gt;inserir&lt;/code&gt; você irá visualizar uma mensagem informando que um novo registro foi inserido e logo abaixo os dados que foram inseridos. Clique agora em &lt;code&gt;Home&lt;/code&gt; e irá ver que o nosso novo post foi listado, faça este processo algumas vezes pra ver que realmente um novo registro está sendo inserido.&lt;/p&gt;

&lt;p&gt;Na parte 05, iremos melhorar o código e criar um formulário para fazer esta inserção com dados que a gente definir. Te vejo lá! 😉&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Remix.run :: CRUD com Supabase - Parte 03 - Configurando o Supabase Client no Remix</title>
      <dc:creator>Junior Martins</dc:creator>
      <pubDate>Tue, 26 Apr 2022 13:45:42 +0000</pubDate>
      <link>https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-03-configurando-o-supabase-client-no-remix-1lhm</link>
      <guid>https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-03-configurando-o-supabase-client-no-remix-1lhm</guid>
      <description>&lt;p&gt;Nesta parte do tutorial iremos criar a configuração que nos permitirá conectar com a API do Supabase.&lt;/p&gt;

&lt;h3&gt;
  
  
  📑 Criando o arquivo &lt;code&gt;.env&lt;/code&gt;
&lt;/h3&gt;

&lt;h5&gt;
  
  
  Passo 01
&lt;/h5&gt;

&lt;p&gt;1) Vá ao Dashboard do Supabase (&lt;a href="https://app.supabase.io/"&gt;https://app.supabase.io/&lt;/a&gt;) e entre no seu projeto &lt;code&gt;Remix Blog Supabase&lt;/code&gt;&lt;br&gt;
2) Na barra lateral, clique no menu &lt;code&gt;Settings&lt;/code&gt; (⚙️), depois em &lt;code&gt;API&lt;/code&gt; e deixe a janela aberta &lt;br&gt;
3) Vá até a raiz do seu projeto.&lt;/p&gt;
&lt;h5&gt;
  
  
  Passo 02
&lt;/h5&gt;

&lt;p&gt;Na raiz do projeto crie o arquivo &lt;code&gt;.env&lt;/code&gt; com as seguintes variáveis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SUPABASE_URL; e&lt;/li&gt;
&lt;li&gt;SUPABASE_KEY.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;
  
  
  Passo 03 - definindo o valor da variável &lt;code&gt;SUPABASE_KEY&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;1) Na janela do Dashboard do Supabase, aquela que deixamos aberta, observe que dentro do formulário &lt;code&gt;Project API Keys&lt;/code&gt; existe o campo &lt;code&gt;anon&lt;/code&gt; &lt;code&gt;public&lt;/code&gt;, clique no botão &lt;code&gt;copy&lt;/code&gt; para capturar o valor dele&lt;br&gt;
2) Agora cole o valor copiado para a variável &lt;code&gt;SUPABASE_KEY&lt;/code&gt; no seu arquivo &lt;code&gt;.env&lt;/code&gt;.&lt;/p&gt;
&lt;h5&gt;
  
  
  Passo 04 - definindo o valor da variável &lt;code&gt;SUPABASE_URL&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;Ainda no Dashboard do Supabase observe que existe o formulário &lt;code&gt;Configuration&lt;/code&gt;. Agora precisamos copiar o valor do campo &lt;code&gt;URL&lt;/code&gt;, para isto clique no botão &lt;code&gt;copy&lt;/code&gt; e cole o valor copiado para a variável &lt;code&gt;SUPABASE_URL&lt;/code&gt; no seu arquivo &lt;code&gt;.env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Se tudo foi feito corretamente seu arquivo &lt;code&gt;.env&lt;/code&gt; deverá ficar parecido com algo assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SUPABASE_URL='https://asxwozcalashinicovpv.supabase.co'
SUPABASE_KEY='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJpc3MiOiAic3VwYWJhc2UiLAogICJyZWYiOiAiYXN4d296Y2FsYXNoaW5pY292cHYiLAogICJyb2xlIjogImFub24iLAogICJpYXQiOiAxNjQ3NzAyMTkxLAogICJleHAiOiAxOTYzMjc4MTkxCn0=.MTPNt7yEGWOvkORubeHDlvEGfH8ZAZcuHq5T878Foec'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Os dados acima são fictícios, portanto não irão funcionar no seu projeto, substitua os dados com os seus!&lt;/em&gt; 😀&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚡️ Criando o cliente do Supabase
&lt;/h3&gt;

&lt;p&gt;Dentro da pasta &lt;code&gt;app&lt;/code&gt;, crie uma subpasta como o nome &lt;code&gt;utils&lt;/code&gt; e dentro dela crie o arquivo &lt;code&gt;supabase-client.server.ts&lt;/code&gt;, que ficará assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//supabase-client.server.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@supabase/supabase-js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;supabaseUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;SUPABASE_URL&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;supabaseKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;SUPABASE_KEY&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;supabaseUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;supabaseKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pronto, nossa conexão com o banco de dados já está pronta, na parte 04 iremos iniciar nosso CRUD propriamente dito.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-01-criando-o-projeto-5bon"&gt;Parte 01 - Criando o projeto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/juniormartinxo/remixrun-crud-com-supabase-parte-02-instalando-o-supabase-4ch7"&gt;Parte 02 - Instalando o Supabase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-03-configurando-o-supabase-client-no-remix-1lhm"&gt;Parte 03 - Configurando o Supabase Client no Remix&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  em breve!
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Parte 04 - Carregando e inserindo novos registros&lt;/li&gt;
&lt;li&gt;Parte 05 - Trabalhando com formulário&lt;/li&gt;
&lt;li&gt;Parte 06 - Testando a inserção de novos registros&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Remix.run :: CRUD com Supabase - Parte 02 - Instalando o Supabase</title>
      <dc:creator>Junior Martins</dc:creator>
      <pubDate>Tue, 26 Apr 2022 13:37:56 +0000</pubDate>
      <link>https://dev.to/juniormartinxo/remixrun-crud-com-supabase-parte-02-instalando-o-supabase-4ch7</link>
      <guid>https://dev.to/juniormartinxo/remixrun-crud-com-supabase-parte-02-instalando-o-supabase-4ch7</guid>
      <description>&lt;h3&gt;
  
  
  Introdução
&lt;/h3&gt;

&lt;p&gt;Nesta parte do tutorial daremos início a configuração da nossa base de dados na página do &lt;a href="https://supabase.com" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt; e nos final faremos a instalação do &lt;a href="https://www.npmjs.com/package/@supabase/supabase-js" rel="noopener noreferrer"&gt;&lt;code&gt;supabase-js&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mas afinal, o quê é o Supabase?
&lt;/h3&gt;

&lt;p&gt;De acordo com a própria página do Supabase ele é uma alternativa de código aberto ao Firebase. Onde, através dele é fornecido todos os serviços necessários para criar o back-end de um produto. Fornecendo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Base de dados em Postgres;&lt;/li&gt;
&lt;li&gt;Autenticação com gerenciamento de usuários;&lt;/li&gt;
&lt;li&gt;Aramazenamento de arquivos; e&lt;/li&gt;
&lt;li&gt;Fornecimento de uma API instantânea&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Criando a base de dados no Supabase
&lt;/h3&gt;

&lt;p&gt;Acesse o link &lt;a href="https://app.supabase.io/" rel="noopener noreferrer"&gt;&lt;code&gt;https://app.supabase.io/&lt;/code&gt;&lt;/a&gt; e logue com sua conta do GitHub clicando no botão &lt;code&gt;Sign In with GitHub&lt;/code&gt;, conforme a imagem abaixo:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzf4xd0xg01um7r0qxm6l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzf4xd0xg01um7r0qxm6l.png" alt="Página de autenticação do Supabase com o título " start=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Será solicitado que você dê autorização, clique no botão &lt;code&gt;Autorize supabase&lt;/code&gt;, conforme a imagem abaixo:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zfx4utn5llrpeo6gp5l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zfx4utn5llrpeo6gp5l.png" alt="Imagem contendo a página de solicitação de autorização de acesso à conta do GitHub. No topo estão lateralizados os logotipos do Supabase, um raio verde, e o do GitHub, um gato. Do lado esquerdo está o logo do Supabase, que está inseiro em um círculo preto, já do lado direito está o logo do GitHub inserido em um círculo cinza. Os logos estão conectados por uma linha tracejada em cinza, que ao centro contem um círculo verde com um ícone de  raw `check` endraw . Abaixo dos logotipos está o título " rel=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feito o login, clique no botão &lt;code&gt;New project&lt;/code&gt;, será solicitado que você selecione uma organização.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Por default o Supabase cria a organização com o &lt;code&gt;usuarioGitHub's Org&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Após selecionar a organização aperecerá um formulário para que você preencha os dados do seu projeto Supabase, conforme a imagem abaixo:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm91wm7su0ifvqyyus3r8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm91wm7su0ifvqyyus3r8.png" alt="Imagem contendo o formulário de criação do projeto, com o título "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Preencha os campos do formulário da seguinte forma:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Name:&lt;/strong&gt; Remix Blog com Supabase&lt;br&gt;
&lt;strong&gt;Database password:&lt;/strong&gt; &lt;em&gt;crie a senha que você quiser&lt;/em&gt; &amp;gt; &lt;strong&gt;Region:&lt;/strong&gt; Para o meu caso o sistema indicou &lt;code&gt;East US (North Virgínia)&lt;/code&gt; &amp;gt; &lt;strong&gt;Princing Plan:&lt;/strong&gt; Free tier&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Preenchido os campos, clique em &lt;code&gt;Create new project&lt;/code&gt; e aguarde o Supabase acabar de criar seu projeto.&lt;/p&gt;

&lt;p&gt;Na janela que será aberta (Project Building) você já terá algumas informações importantes do seu projeto, como Project API Keys e Project Configuration, as quais não iremos utilizar agora.&lt;/p&gt;
&lt;h3&gt;
  
  
  Criando a nossa tabela do Blog
&lt;/h3&gt;

&lt;p&gt;O Dashboard do Supabase possui um menu lateral onde ficam os links que irão direcionar para os serviços que são disponibilizados:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8icasro4aiah7jvvg9aw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8icasro4aiah7jvvg9aw.png" alt="Imagem do menu lateral do Supabase, contendo Home, Table Editor Authentication, Storage, SQL Editor, Database, Reports, API e Settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clique no menu &lt;code&gt;Table editor&lt;/code&gt; e depois em &lt;code&gt;Create new table&lt;/code&gt;. No formulário que será aberto preencha com:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Name:&lt;/strong&gt; posts&lt;br&gt;
&lt;strong&gt;Description:&lt;/strong&gt; Posts do nosso Blog&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E adicione as colunas abaixo clicando em &lt;code&gt;add column&lt;/code&gt;:&lt;br&gt;
&lt;em&gt;Particularmente, eu gosto de adicionar sufixos aos nomes dos campos das minhas tabelas. É um gosto pessoal, pois acho mais descritivo. Você é livre para criar os campos com os nomes da forma que você quiser.&lt;/em&gt; 😉&lt;/p&gt;
&lt;h4&gt;
  
  
  A tabela &lt;code&gt;posts&lt;/code&gt; ficará assim:
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;type&lt;/th&gt;
&lt;th&gt;Default value&lt;/th&gt;
&lt;th&gt;Primary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;post_id&lt;/td&gt;
&lt;td&gt;int8&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;checked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;post_uuid&lt;/td&gt;
&lt;td&gt;uuid&lt;/td&gt;
&lt;td&gt;uuid_generate_v4()&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;post_author&lt;/td&gt;
&lt;td&gt;text&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;post_title&lt;/td&gt;
&lt;td&gt;text&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;post_text&lt;/td&gt;
&lt;td&gt;text&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;post_situation&lt;/td&gt;
&lt;td&gt;varchar&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;post_created_at&lt;/td&gt;
&lt;td&gt;timestamptz&lt;/td&gt;
&lt;td&gt;now()&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Adicionados os campos, clique em &lt;code&gt;create&lt;/code&gt;. Se tudo estiver corrido bem a tabela &lt;code&gt;posts&lt;/code&gt; aparecerá em &lt;code&gt;Table editor&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Instalando o Supabase no nosso projeto
&lt;/h3&gt;

&lt;p&gt;Vá até a pasta raiz do projeto, onde o &lt;code&gt;remix-supabase&lt;/code&gt; foi criado e rode o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -E @supabase/supabase-js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando instalará o cliente do supabase na nossa aplicação.&lt;/p&gt;

&lt;p&gt;Na parte 03 iremos criar o nosso cliente Supabase na nossa aplicação. Te vejo lá! 😉&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-01-criando-o-projeto-5bon"&gt;Parte 01 - Criando o projeto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/juniormartinxo/remixrun-crud-com-supabase-parte-02-instalando-o-supabase-4ch7"&gt;Parte 02 - Instalando o Supabase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-03-configurando-o-supabase-client-no-remix-1lhm"&gt;Parte 03 - Configurando o Supabase Client no Remix&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  em breve!
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Parte 04 - Carregando e inserindo novos registros&lt;/li&gt;
&lt;li&gt;Parte 05 - Trabalhando com formulário&lt;/li&gt;
&lt;li&gt;Parte 06 - Testando a inserção de novos registros&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Remix.run :: CRUD com Supabase - Parte 01 - Criando o projeto</title>
      <dc:creator>Junior Martins</dc:creator>
      <pubDate>Tue, 26 Apr 2022 13:32:27 +0000</pubDate>
      <link>https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-01-criando-o-projeto-5bon</link>
      <guid>https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-01-criando-o-projeto-5bon</guid>
      <description>&lt;h3&gt;
  
  
  Introdução
&lt;/h3&gt;

&lt;p&gt;Olá! Neste tutorial você aprenderá como fazer um CRUD completo usando Remix e Supabase. Iremos abordar desde a instalção da aplicação com Remix, passando pela criação de uma conta no &lt;a href="https://supabase.com/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt;, criação de tabelas e configuração para comunicação com a API até a criação de um formulário que permitirá a inserção de novos registros.&lt;/p&gt;

&lt;p&gt;Faremos um CRUD completo com estas duas ferramentas maravilhosas e que sou suspeito de falar, mas não consigo ver você não se apaixonando ao término de passo-a-passo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Techs utilizadas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://remix.run/" rel="noopener noreferrer"&gt;Remix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://supabase.com/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/pt-br/learn/modules/typescript-get-started/" rel="noopener noreferrer"&gt;Typescript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pré-requisitos
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Uma conta no &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Node.js 14 ou superior&lt;/li&gt;
&lt;li&gt;npm 7 ou superior&lt;/li&gt;
&lt;li&gt;Um editor de código de sua preferência, aqui utilizaremos o VSCode&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Iniciando o projeto
&lt;/h3&gt;

&lt;p&gt;O primeiro passo que iremos dar será criar nosso projeto e para isto utilizaremos o comando:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx create-remix@latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O comando iniciará o setup que criará sua aplicação Remix, deixe as respostas assim:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Need to install the following packages:&lt;br&gt;
create-remix@latest&lt;br&gt;
Ok to proceed? (y) y&lt;/p&gt;

&lt;p&gt;? Where would you like to create your app? (./my-remix-app): &lt;strong&gt;remix-supabase&lt;/strong&gt;&lt;br&gt;
? What type of app do you want to create? (Use arrow keys): &lt;strong&gt;Just the bascis&lt;/strong&gt;&lt;br&gt;
? Where do you want to deploy? Choose Remix if you're unsure, it's easy to change deployment targets. (Use arrow keys): &lt;strong&gt;Remix App Server&lt;/strong&gt;&lt;br&gt;
? TypeScript or JavaScript? (Use arrow keys): &lt;strong&gt;Typescript&lt;/strong&gt;&lt;br&gt;
? Do you want me to run 'npm install'? (Y/n) &lt;strong&gt;Y&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Finalizada a instalação, abra o projeto criado com o editor de sua preferência:&lt;/p&gt;

&lt;p&gt;Se assim como eu, você estiver utilizando o &lt;code&gt;VSCode&lt;/code&gt;, basta digitar os comandos abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; cd remix-supabase
&amp;gt; code .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Testando se tudo foi criado corretamente
&lt;/h3&gt;

&lt;p&gt;Para testar se sua aplicação REMIX foi criada de forma correta rode o comando:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Deve aparecer a seguinte mensagem no terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; dev
&amp;gt; remix dev

Watching Remix app in development mode...
💿 Built in 1.4s
Remix App Server started at http://localhost:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Acesse &lt;code&gt;http://localhost:3000&lt;/code&gt; e veja que existe um app Remix rodando, conforme a imagem abaixo:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fruzo1fbdrzzmmwzw8z8h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fruzo1fbdrzzmmwzw8z8h.png" alt="Imagem da aplicação default do REMIX, com o título "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Estrutura do projeto Remix
&lt;/h3&gt;

&lt;p&gt;O Remix criará várias pastas no seu projeto, mas a mais importante e que iremos trabalhar será a pasta &lt;code&gt;app&lt;/code&gt;, que é onde toda a mágica acontece. Dentro da pasta &lt;code&gt;app&lt;/code&gt; você encontrará a pasta &lt;code&gt;routes&lt;/code&gt;, que é onde ficam as rotas da nossa aplicação. A pasta &lt;code&gt;routes&lt;/code&gt; é primoridal, pois ela é o cerne de tudo e é nela que toda simplicidade do Remix ganha força.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnq9beep32cxm29qrqlol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnq9beep32cxm29qrqlol.png" alt="A imagem traz a estrutura das pastas principais do Remix listadas em: .cache, app&amp;gt;routes, build, node_modules e public e os arquivos .eslintrc, .gitignore, package-lock.json, package.json, README[dot]md, remix.config.js, remix.env.d.ts e tsconfig.json"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na parte 02 criaremos a nossa base de dados no Supabase e faremos a instalação do &lt;code&gt;supabase-js&lt;/code&gt; na nossa aplicação. Te vejo lá! 😉&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-01-criando-o-projeto-5bon"&gt;Parte 01 - Criando o projeto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/juniormartinxo/remixrun-crud-com-supabase-parte-02-instalando-o-supabase-4ch7"&gt;Parte 02 - Instalando o Supabase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/juniormartinxo/remix-crud-com-supabase-parte-03-configurando-o-supabase-client-no-remix-1lhm"&gt;Parte 03 - Configurando o Supabase Client no Remix&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  em breve!
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Parte 04 - Carregando e inserindo novos registros&lt;/li&gt;
&lt;li&gt;Parte 05 - Trabalhando com formulário&lt;/li&gt;
&lt;li&gt;Parte 06 - Testando a inserção de novos registros&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>remix</category>
      <category>supabase</category>
      <category>javascript</category>
      <category>react</category>
    </item>
  </channel>
</rss>
