<?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: David Dias</title>
    <description>The latest articles on DEV Community by David Dias (@thedaviddias).</description>
    <link>https://dev.to/thedaviddias</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%2F34747%2F00f60433-fa3a-4f6a-80b3-d6641cbdbe00.jpeg</url>
      <title>DEV Community: David Dias</title>
      <link>https://dev.to/thedaviddias</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thedaviddias"/>
    <language>en</language>
    <item>
      <title>I Ditched My AI Agent Dashboard for Obsidian</title>
      <dc:creator>David Dias</dc:creator>
      <pubDate>Sun, 08 Feb 2026 15:46:00 +0000</pubDate>
      <link>https://dev.to/thedaviddias/i-ditched-my-ai-agent-dashboard-for-obsidian-37la</link>
      <guid>https://dev.to/thedaviddias/i-ditched-my-ai-agent-dashboard-for-obsidian-37la</guid>
      <description>&lt;p&gt;I spent a few days building a React dashboard. Dark mode, real-time updates, graphs showing agent activity across my network. My agents helped me build it. It looked incredible. I showed it to a friend and they said "wow, that's impressive." Then I deleted the entire repository.&lt;/p&gt;

&lt;p&gt;Something felt wrong. I couldn't put my finger on it at first. But the more I worked with it, the more I realized I was solving the wrong problem. I was building a UI that will probably be obsolete at some point. With the ultra-fast evolution of &lt;a href="https://openclaw.ai/" rel="noopener noreferrer"&gt;OpenClaw&lt;/a&gt;, it's another app I would have to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Dashboard Trap
&lt;/h2&gt;

&lt;p&gt;The idea seemed smart. I have multiple AI agents running on different machines. They need coordination. They need to share state. They need to report what they're doing. What better solution than a beautiful dashboard?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4k6k8qpq3hhy5s1dmzgi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4k6k8qpq3hhy5s1dmzgi.png" alt="Screenshot of my dashboard showing different agents and a kanban board" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I built one. WebSocket connections. Agent status indicators. Task queues visualized with drag-and-drop. I even added a dark mode toggle because of course I did.&lt;/p&gt;

&lt;p&gt;Then came the maintenance. One agent would fail to report and I'd spend an hour not knowing it had failed silently. The dashboard itself became a project that needed its own dashboard.&lt;/p&gt;

&lt;p&gt;It hit me during a weekend when I wanted to check on my agents but couldn't because the server was down. I was locked out of my own system because the UI layer failed. That's when I realized: I had built a cage for myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;If you look around. Everyone building AI agents is also building some sort of complex UIs to coordinate them. We have agent frameworks with admin panels. Status dashboards with graphs and charts. It's beautiful, but is it necessary?&lt;/p&gt;

&lt;p&gt;Agents are programs. They can read files. They can write files. They don't need a "dashboard." They need data. The dashboard is for us. And we already have tools to read and write data.&lt;/p&gt;

&lt;p&gt;The problem isn't coordination. It's that we're over-engineering the coordination layer because that's what we're used to doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Dumb" Solution
&lt;/h2&gt;

&lt;p&gt;I deleted the React dashboard.&lt;/p&gt;

&lt;p&gt;Then I opened &lt;a href="https://obsidian.md/" rel="noopener noreferrer"&gt;Obsidian&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I created a folder called &lt;code&gt;07-agents/&lt;/code&gt; in my vault. Each agent got its own subfolder with three files: &lt;code&gt;SOUL.md&lt;/code&gt; (its personality and purpose), a kanban-style task list, and a &lt;code&gt;reports/&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;That's it. No UI. No database. Just markdown files in a folder structure.&lt;/p&gt;

&lt;p&gt;I updated AGENTS.md and created a skill to ensure that the agents knew what, how and where to create files.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Actually Works
&lt;/h2&gt;

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

&lt;p&gt;My setup is intentionally simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separated Linux server with OpenClaw (on a small NUC)&lt;/li&gt;
&lt;li&gt;Mac with Obsidian: I work on my laptop. This is where I read reports, assign tasks, and review what the agents are doing.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://linux.die.net/man/1/rsync" rel="noopener noreferrer"&gt;rsync&lt;/a&gt;over &lt;a href="https://tailscale.com/" rel="noopener noreferrer"&gt;Tailscale&lt;/a&gt;: every 5 minutes, a cron job syncs the &lt;code&gt;07-agents/&lt;/code&gt; folder between my server and my laptop using rsync over SSH through Tailscale. No complex sync engine. Just a command that runs in the background.&lt;/li&gt;
&lt;li&gt;Agents read/write markdown files: when an agent needs to report something, it appends to a markdown file. When it needs a new task, it reads its task list. Just file I/O.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Jarvis, my main agent ensures every X mins, that the agents know they have a folder of files to work with and they successfully do their tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;I use the PARA method for my Obsidian vault, so agents live in their own corner: &lt;code&gt;07-agents/&lt;/code&gt;. Each agent has a consistent structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SOUL.md&lt;/code&gt;. The agent's personality, capabilities, and boundaries. This is their definition file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Task List.md&lt;/code&gt;. A kanban board in markdown. Backlog, In Progress, Review, Done.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;reports/&lt;/code&gt;. A folder where the agent dumps its daily reports, findings, and outputs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;knowledge/&lt;/code&gt;. Reference material the agent needs to do its job.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I use &lt;a href="https://obsidian.md/plugins?search=dataview" rel="noopener noreferrer"&gt;Dataview&lt;/a&gt; to create dashboards. A simple query gives me a view of all in-progress tasks across all agents. Another query shows me recent reports. It's not real-time in the web dashboard sense, but it's real enough. I refresh when I want updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Benefits
&lt;/h2&gt;

&lt;p&gt;This setup has advantages I didn't anticipate:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Offline capable&lt;/strong&gt;: I can work on my laptop without internet. The agents keep running. When I reconnect, rsync catches up. No sync conflicts, no "you have unsaved changes" warnings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plain text = future proof&lt;/strong&gt;: markdown isn't going anywhere. Even if Obsidian disappeared tomorrow, I'd still have readable files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No UI maintenance&lt;/strong&gt;: I don't maintain a UI anymore. The UI is Obsidian, which someone else maintains. I just write markdown.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portable&lt;/strong&gt;: I can access agent data from any device that reads text files. My phone. A tablet. A borrowed computer. No authentication flow required.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Git-friendly&lt;/strong&gt;: the entire coordination layer can be version controlled. I can see exactly what an agent did yesterday by looking at git history.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Technical Deep Dive
&lt;/h2&gt;

&lt;p&gt;For those who want to try this, here's the actual setup:&lt;/p&gt;

&lt;p&gt;The rsync command is simpler than you'd expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-avz&lt;/span&gt; &lt;span class="nt"&gt;--delete&lt;/span&gt; &lt;span class="nt"&gt;--exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'.git'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"ssh -i ~/.ssh/agent_sync"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  ~/obsidian/07-agents/ &lt;span class="se"&gt;\&lt;/span&gt;
  server:/home/agents/vault/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(I confess that my agent did the whole setup...) 😬&lt;/p&gt;

&lt;p&gt;I run this every 5 minutes via cron. The &lt;code&gt;--exclude='.git'&lt;/code&gt; is important. I learned that the hard way when git corruption caused sync issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conflict resolution&lt;/strong&gt; is simple: newer wins. rsync handles this. If I edit a task on my laptop while an agent updates its status, whichever finishes last persists. In practice, this almost never causes problems because agents mostly append to files, and I mostly edit task lists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Health monitoring&lt;/strong&gt; comes through Telegram. Each agent sends me a daily message: tasks completed, any blockers, and a status emoji. If I don't get the message, something's wrong. It's lo-fi, but it works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The key insight:&lt;/strong&gt; Agents don't need to know about each other. They just need to know about files. If Agent A writes a report that Agent B needs to read, that's just filesystem permissions. No message bus required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Wins
&lt;/h2&gt;

&lt;p&gt;I spent a few days building complexity with agent help and two hours replacing it with simplicity. The simple solution works better.&lt;/p&gt;

&lt;p&gt;The dashboard I built was impressive. It was also unnecessary. Agents don't need dashboards. They need data. Humans don't need real-time graphs. We need context.&lt;/p&gt;

&lt;p&gt;Markdown files in a synced folder give both groups exactly what they need. Agents get structured data they can parse. Humans get readable documents they can understand. No translation layer required.&lt;/p&gt;

&lt;p&gt;The best part? When something breaks, I can debug it with &lt;code&gt;cat&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt;. I don't need to check server logs and database connections. I just look at the files.&lt;/p&gt;

&lt;p&gt;Sometimes the dumb solution is the smart one.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What would you simplify in your setup if you weren't afraid of looking unsophisticated?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>openclaw</category>
      <category>obsidian</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Getting Started with llms.txt</title>
      <dc:creator>David Dias</dc:creator>
      <pubDate>Thu, 27 Feb 2025 05:04:42 +0000</pubDate>
      <link>https://dev.to/thedaviddias/getting-started-with-llmstxt-5dc9</link>
      <guid>https://dev.to/thedaviddias/getting-started-with-llmstxt-5dc9</guid>
      <description>&lt;p&gt;Learn how to implement llms.txt in your website or documentation&lt;/p&gt;

&lt;h2&gt;
  
  
  What is llms.txt?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;llms.txt&lt;/code&gt; file is a &lt;a href="https://llmstxt.org/" rel="noopener noreferrer"&gt;proposed standard&lt;/a&gt; that helps AI models better understand and interact with your website's content. Unlike &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Robots.txt" rel="noopener noreferrer"&gt;robots.txt&lt;/a&gt; or &lt;a href="https://developers.google.com/search/docs/crawling-indexing/sitemaps/overview" rel="noopener noreferrer"&gt;sitemap.xml&lt;/a&gt;, it's specifically designed to enhance AI interactions by providing structured content overviews and navigation paths.&lt;/p&gt;

&lt;h3&gt;
  
  
  Purpose and Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced AI Understanding&lt;/strong&gt;: Provides a structured overview of your website content, helping AI systems understand your site quickly and accurately&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficient Information Retrieval&lt;/strong&gt;: Enables AI systems to locate and retrieve relevant information efficiently&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved Contextual Understanding&lt;/strong&gt;: Reduces misinterpretation by providing context and relationships between content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better User Experience&lt;/strong&gt;: Leads to more accurate, context-aware responses when users interact with AI about your content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overcoming Context Limitations&lt;/strong&gt;: Helps AI systems work within their context window limitations by providing streamlined content access&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How llms.txt Differs from robots.txt and sitemap.xml
&lt;/h2&gt;

&lt;p&gt;While these files might seem similar, they serve distinct purposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;robots.txt&lt;/strong&gt;: Focuses on controlling search engine crawler access but doesn't help with content understanding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sitemap.xml&lt;/strong&gt;: Lists all indexable pages without providing context or helping with content processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;llms.txt&lt;/strong&gt;: Specifically addresses AI-related challenges by providing content structure in a format optimized for AI processing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The llms.txt Specification
&lt;/h2&gt;

&lt;p&gt;The specification defines two distinct files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;/llms.txt&lt;/strong&gt;: A streamlined view of documentation navigation to help AI systems quickly understand a site's structure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;/llms-full.txt&lt;/strong&gt;: A comprehensive file containing all documentation in one place&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both files use Markdown formatting, which provides a natural hierarchy that AI models can easily parse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Implementation Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create the File Structure
&lt;/h3&gt;

&lt;p&gt;The llms.txt file uses Markdown with a specific structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Your Website/Project Name&lt;/span&gt;
&lt;span class="gt"&gt;
&amp;gt; A brief description of your website or project&lt;/span&gt;

&lt;span class="gu"&gt;## Documentation&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Getting Started&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/docs/getting-started&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; - Guide for new users
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;API Reference&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/docs/api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; - Complete API documentation
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Tutorials&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/docs/tutorials&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; - Step-by-step guides

&lt;span class="gu"&gt;## Examples&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Basic Implementation&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/examples/basic&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; - Simple integration example
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Advanced Features&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/examples/advanced&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; - Using advanced capabilities

&lt;span class="gu"&gt;## Optional Resources&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Community Forum&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/community&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; - Get help from other users
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Change Log&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/changelog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; - Track updates and changes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Place the File in the Correct Location
&lt;/h3&gt;

&lt;p&gt;Save the file as &lt;code&gt;llms.txt&lt;/code&gt; in your website's root directory, ensuring it's accessible at &lt;code&gt;yourwebsite.com/llms.txt&lt;/code&gt;. If you're creating a comprehensive version with all your documentation, save it as &lt;code&gt;llms-full.txt&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Add HTTP Headers (Optional but Recommended)
&lt;/h3&gt;

&lt;p&gt;Add the following HTTP header to your server configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X-Robots-Tag: llms-txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Verify Implementation
&lt;/h3&gt;

&lt;p&gt;Test your implementation by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Accessing &lt;code&gt;yourwebsite.com/llms.txt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Checking HTTP headers&lt;/li&gt;
&lt;li&gt;Validating the file format&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Using llms.txt with AI Systems
&lt;/h2&gt;

&lt;p&gt;Currently, most AI models don't automatically discover and index llms.txt files. To use your llms.txt file with AI systems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Direct Link&lt;/strong&gt;: Provide the AI with a link to your llms.txt file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual Copy&lt;/strong&gt;: Copy the contents of your llms.txt file directly into your prompt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File Upload&lt;/strong&gt;: Use the AI tool's file upload feature if available&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As adoption increases, more AI systems will likely integrate automatic discovery of llms.txt files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where To Find a list of all llms.txt files?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftb77bygg79aa02gbsrd4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftb77bygg79aa02gbsrd4.jpg" alt="Screenshot of the llms.txt hub website showing a dark-themed interface with navigation menu, welcome message explaining the platform for AI-ready documentation, featured websites section (Warp, Galileo, raincamp, Dopp Finance), and a three-step guide explaining how the llms.txt standard works." width="800" height="621"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://llmstxthub.com" rel="noopener noreferrer"&gt;llms.txt hub&lt;/a&gt; is rapidly becoming a popular open-source hub tracking all the websites that have implemented the llms.txt and llms-full.txt standards. Updated regularly, this comprehensive directory allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Discover real-world implementations across various industries and platforms&lt;/li&gt;
&lt;li&gt;Study how leading organizations structure their llms.txt files&lt;/li&gt;
&lt;li&gt;Access the latest news and developments related to the standard&lt;/li&gt;
&lt;li&gt;Find open-source tools, plugins, and resources for implementing llms.txt on your own website&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By exploring this directory, developers and content creators can observe implementation patterns, stay informed about best practices, and connect with the growing community of websites optimizing their content for AI systems through the llms.txt standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generation Tools
&lt;/h2&gt;

&lt;p&gt;Several tools can help you generate llms.txt files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotenvx/llmstxt" rel="noopener noreferrer"&gt;llmstxt by dotenv&lt;/a&gt;: Open source CLI tool that generates &lt;code&gt;llms.txt&lt;/code&gt; based on a site's &lt;code&gt;sitemap.xml&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://llmstxt.firecrawl.dev/" rel="noopener noreferrer"&gt;llmstxt by Firecrawl&lt;/a&gt;: Uses Firecrawl to generate a llms.txt file.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://mintlify.com/blog/simplifying-docs-with-llms-txt" rel="noopener noreferrer"&gt;Mintlify&lt;/a&gt;: Documentation platform with llms.txt generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Friso2v7nwe6n2v48mxm6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Friso2v7nwe6n2v48mxm6.jpg" alt="The image shows a dark-themed web interface titled " width="800" height="687"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Examples
&lt;/h2&gt;

&lt;p&gt;Many organizations have already adopted the llms.txt proposed standard:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://llmstxthub.com/website/cloudflare" rel="noopener noreferrer"&gt;Cloudflare&lt;/a&gt;: Impressive and extensive documentation about all the Cloudflare services&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://llmstxthub.com/website/anthropic" rel="noopener noreferrer"&gt;Anthropic's llms.txt&lt;/a&gt;: All their documentation and prompt library&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://llmstxthub.com/website/perplexity" rel="noopener noreferrer"&gt;Perplexity's llms-full.txt&lt;/a&gt;: A comprehensive implementation all their documentation and content website&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://llmstxthub.com/website/elevenlabs" rel="noopener noreferrer"&gt;ElevenLabs&lt;/a&gt;: All the documenation about their API and product guides&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keep it Updated&lt;/strong&gt;: Regularly update your llms.txt file as your website structure changes to ensure AI systems have the most current information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Use Clear Markdown Structure&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with an H1 project name&lt;/li&gt;
&lt;li&gt;Include a blockquote summary&lt;/li&gt;
&lt;li&gt;Use H2 headers to organize documentation links&lt;/li&gt;
&lt;li&gt;Provide brief descriptions for each link&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Be Selective&lt;/strong&gt;: Focus on the most important resources in llms.txt, using the Optional section for less critical content.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Test with AI Systems&lt;/strong&gt;: Verify that AI models correctly interpret and navigate your content based on your llms.txt file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Optimize for AI Processing&lt;/strong&gt;: Remove non-essential markup and scripts in llms-full.txt to help AI models focus on the important content.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://llmstxt.org" rel="noopener noreferrer"&gt;llms.txt Standard Proposal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thedaviddias/llms-txt-hub" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thedaviddias/llms-txt-hub/discussions" rel="noopener noreferrer"&gt;Community Forum&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>llmstxt</category>
      <category>llm</category>
      <category>ai</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Beyond User Testing: Leveraging Frontend Experience</title>
      <dc:creator>David Dias</dc:creator>
      <pubDate>Sat, 10 Jun 2023 20:49:00 +0000</pubDate>
      <link>https://dev.to/thedaviddias/beyond-user-testing-leveraging-frontend-experience-2a3c</link>
      <guid>https://dev.to/thedaviddias/beyond-user-testing-leveraging-frontend-experience-2a3c</guid>
      <description>&lt;p&gt;User testing is a crucial tool for gathering feedback on a product, but it's not enough to truly understand and improve user engagement. For the past 13 years, I have been building multi-language platforms for international brands and for a wide variety of users. Even in a space that constantly changes, where users have evolving needs, it's important to also acknowledge the role that experience plays in understanding them.&lt;/p&gt;

&lt;p&gt;&lt;a href="/images/articles/beyond-user-testing-leveraging-frontend-experience/table-computers.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/images/articles/beyond-user-testing-leveraging-frontend-experience/table-computers.jpg" title="Photo by &amp;lt;a href="&gt;&lt;/a&gt;Marvin Meyer on Unsplash"/&amp;gt;&lt;/p&gt;

&lt;p&gt;Being a Front-End Developer gave me and all my colleagues around the world a unique perspective on user experience. We understand how small design decisions can have a big impact on the user experience, and we have a deep understanding of how users interact with products. By leveraging our experience in front-end development, we can help create products that are not only effective but also enjoyable to use, leading to increased user satisfaction and loyalty.&lt;/p&gt;

&lt;h2&gt;
  
  
  The limits of user testing
&lt;/h2&gt;

&lt;p&gt;User testing is a critical component of product development that can help identify usability issues and gather feedback from real users. By testing products with representative users, product teams can gain valuable insights in how users interact with their interfaces and what their pain points are. Whatever you use services like &lt;a href="https://www.usertesting.com/" rel="noopener noreferrer"&gt;User Testing&lt;/a&gt;, or your own user testing directly with regular users, user testing also possess some limits that can’t be overlooked.&lt;/p&gt;

&lt;p&gt;For example, users may not always be able to articulate their needs and preferences accurately, or identify more obvious usability issues that sometimes are more subtle or hidden. User testing is also typically conducted in a controlled environment, which may not always accurately reflect real-wold usage scenarios.&lt;/p&gt;

&lt;p&gt;What about people that don’t use technology in a daily basis?&lt;/p&gt;

&lt;p&gt;Usually user testing is done by a certain user group or demographics and don’t include 100% of all users. From my point of view, user testing can’t be really complete without testing with people with disabilities. For people with experience in doing accessibility testing with real users, I’m sure you will agree that.&lt;/p&gt;

&lt;h2&gt;
  
  
  User testing can lead to success or failure
&lt;/h2&gt;

&lt;p&gt;Through Internet history, user testing had lead to create successful products:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slack (which I daily use) is a popular communication tool. During its development, Slack's team conducted user testing to identify usability issues and gather feedback from its target users. This feedback helped them make improvements to the platform, resulting in a product that was easier to use and more engaging for its users.&lt;/li&gt;
&lt;li&gt;Dropbox is a cloud storage platform that allows users to store, share, and collaborate on files. Dropbox's team used user testing to identify pain points and improve the user experience, resulting in a product that was more intuitive and engaging for its users.&lt;/li&gt;
&lt;li&gt;And a lot more…!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But user testing can also fail to uncover critical usability issues which can contribute to the failure of some projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Wave was a communication and collaboration platform that was introduced in 2009. User testing suggested that users would appreciate the platform's advanced features and integration with other Google products, but when it was released to the market, &lt;a href="https://www.taskade.com/blog/google-wave-history/" rel="noopener noreferrer"&gt;users found the platform confusing and difficult to use&lt;/a&gt;, leading to low adoption rates and eventually the discontinuation of the product in January 2018.&lt;/li&gt;
&lt;li&gt;The Amazon Fire Phone was a smartphone introduced by Amazon in 2014. User testing suggested that users would appreciate the phone's unique features, such as the dynamic perspective display, but when it was released to the market, &lt;a href="https://maestrolearning.com/blogs/amazon-fire-phone/" rel="noopener noreferrer"&gt;users found the phone overpriced and underwhelming&lt;/a&gt;, leading to poor sales and eventually the discontinuation of the product. The lack of empathy towards the users needs was also part of the reasons why it failed.&lt;/li&gt;
&lt;li&gt;Twitter timeline algorithm: In 2016, Twitter also faced public outrage when they introduced an algorithm-based timeline, which did not align with users' preferences for a chronological timeline that allowed them to see real-time tweets in ascending order.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Building a successful project is not an easy task, a lot of factors can influence the success or the failure of a new product. Nowadays, users have different needs. Users switch faster to competitor then before, we have daily examples of that.&lt;/p&gt;

&lt;p&gt;User testing is one tool in companies belt that should be used as often as possible, but shouldn’t be the only one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leveraging Front-End experience
&lt;/h2&gt;

&lt;p&gt;Front-End Developers (FED) are not just coders. Usually seen as the ones that “just” integrate designs into HTML, CSS and JavaScript, their &lt;a href="https://infinum.com/blog/t-shaped-developers/" rel="noopener noreferrer"&gt;t-shape personalities&lt;/a&gt; is often times overlooked (not all FES have t-shape skills though).&lt;/p&gt;

&lt;p&gt;A FED can play a critical role in creating engaging user experiences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Collaboration and communication for better user engagement
&lt;/h2&gt;

&lt;p&gt;As I said in &lt;a href="https://thedaviddias.dev/articles/how-front-end-developers-ui-ux-could-better-collaborate-together" rel="noopener noreferrer"&gt;my previous article&lt;/a&gt; about Front-End Developers, Web and UX/UI Designers collaboration, collaboration and communication is key in building a successful product.&lt;/p&gt;

&lt;p&gt;This collaborative approach allows different perspectives to merge and create a more holistic vision of the product. As Front-End Developers, we have the unique position of working at the intersection of design and technology. We are often the ones who bring the designers' visions to life while ensuring that the product remains functional and user-friendly.&lt;/p&gt;

&lt;p&gt;Front-end development is about more than just making things look good. It's about creating a seamless and intuitive interface that guides users through a product. Every button, every transition, every piece of interactive content is a chance to engage users and keep them invested in the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Benefits of Leveraging Front-End Experience
&lt;/h2&gt;

&lt;p&gt;Front-end developers have a deep understanding of user behavior, as they are responsible for creating the interactive elements that users engage with. They can use this knowledge to create more engaging user interfaces and to guide user testing to focus on areas of the product that are most likely to affect user engagement.&lt;/p&gt;

&lt;p&gt;Beyond just implementing designs, a seasoned FED can provide insights and suggest improvements to the UX/UI designs based on their knowledge of what is technically feasible and what would create a smoother user journey. They can spot potential pitfalls in the designs that might be overlooked during user testing.&lt;/p&gt;

&lt;p&gt;For example, a developer might notice that a particular design element could cause issues on certain devices or browsers. They might also suggest an alternative way of implementing a feature that enhances the user's experience. I have been advocating about accessibility for years now. Last year, I became &lt;a href="https://www.accessibilityassociation.org/s/certified-professional" rel="noopener noreferrer"&gt;CPACC certified&lt;/a&gt; and I continue to advocate for accessibility in my daily work. Not everyone understand what web accessibility is and how it impacts users. It takes time and effort to educate people about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future of User Engagement
&lt;/h2&gt;

&lt;p&gt;As technology advances, users' expectations also rise. They demand faster, smoother, and more intuitive interfaces. User testing will always be a vital tool for gathering feedback, but to meet these evolving demands, we need to go beyond testing.&lt;/p&gt;

&lt;p&gt;Incorporating the front-end developer's expertise into the design process and user testing can help create a product that not only meets the users' needs but also provides an engaging and satisfying experience.&lt;/p&gt;

&lt;p&gt;We must continue to push the boundaries, experiment with new technologies, and constantly seek ways to better understand and improve user engagement. Only by doing this can we hope to create products that users will love to use.&lt;/p&gt;

&lt;p&gt;Front-End Developers bring a valuable perspective to the product development process. Let's use it to its fullest potential to create engaging, user-friendly products. After all, the success of any product lies in the satisfaction of its users.&lt;/p&gt;




&lt;p&gt;At the end, user engagement is not just about the single experience of a product but the entire journey. It's about creating an engaging, intuitive, and satisfying journey that users want to return to again and again. And Front-End Developers play a crucial role in crafting this journey.&lt;/p&gt;

&lt;p&gt;Remember, user testing is a part of the journey, not the destination. We must use all the tools at our disposal, and that includes leveraging the front-end development experience to truly understand and improve user engagement.&lt;/p&gt;

&lt;p&gt;Let's continue to build with the user in mind, always striving to enhance their journey, their experience, and ultimately, their engagement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;"&lt;a href="https://www.smashingmagazine.com/2012/06/the-importance-of-user-testing-in-product-development/" rel="noopener noreferrer"&gt;The Importance of User Testing in Product Design&lt;/a&gt;" by Smashing Magazine&lt;/li&gt;
&lt;li&gt;"&lt;a href="https://www.adobe.com/creativecloud/design/discover/experience-design.html" rel="noopener noreferrer"&gt;Experience Design: What It Is and Why It Matters&lt;/a&gt;" by Adobe XD Ideas&lt;/li&gt;
&lt;li&gt;"&lt;a href="https://uxdesign.cc/why-user-experience-matters-to-front-end-developers-583e3c3a4f4b" rel="noopener noreferrer"&gt;Why User Experience Matters to Front-End Developers&lt;/a&gt;" by UX Design&lt;/li&gt;
&lt;li&gt;"&lt;a href="https://www.usertesting.com/blog/benefits-of-combining-user-testing-and-ux-design/" rel="noopener noreferrer"&gt;The Benefits of Combining User Testing and UX Design&lt;/a&gt;" by UserTesting&lt;/li&gt;
&lt;li&gt;"&lt;a href="https://echobind.com/blog/why-user-experience-ux-is-vital-for-front-end-developers/" rel="noopener noreferrer"&gt;Why User Experience (UX) is Vital for Front-End Developers&lt;/a&gt;" by Echobind&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>ux</category>
      <category>testing</category>
      <category>frontend</category>
    </item>
    <item>
      <title>9 Best Practices &amp; UX improvements for the two-factor authentication (2FA)</title>
      <dc:creator>David Dias</dc:creator>
      <pubDate>Fri, 26 Feb 2021 00:30:00 +0000</pubDate>
      <link>https://dev.to/thedaviddias/9-best-practices-ux-improvements-for-the-two-factor-authentication-2fa-50m6</link>
      <guid>https://dev.to/thedaviddias/9-best-practices-ux-improvements-for-the-two-factor-authentication-2fa-50m6</guid>
      <description>&lt;p&gt;In 2023 alone, cybercriminals will steal 33 billion records. It takes 196 days on average to identify a data breach. The cost of a data breach will reach $150 million by 2020...&lt;br&gt;
These numbers may be scary but they are only previsions. Things could be much worse in the near future. Security has become a hot topic these last years, almost everyone on the planet has already heard about a company data breach or even a friend that lost his Facebook account because someone hacked it! No one is completely safe nowadays.&lt;/p&gt;

&lt;p&gt;I've recently spent multiple hours ensuring that all the accounts I possess use a unique password, complex and long with at least 20 characters and with the two-factor authentication (2FA) enable if present. I've discovered so many disparities between companies and so many issues in terms of features and user experience. I wanted to share with you in this article, what I believe are the best and recommended features for any website or company that takes the security of its users seriously.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Offer two-factor authentication options
&lt;/h2&gt;

&lt;p&gt;That is the starting point.&lt;/p&gt;

&lt;p&gt;If you care about your users or customers, you should give them the choice to activate the two-factor authentication. On around 800 websites where I have an account, &lt;strong&gt;only 5% offer a 2FA option&lt;/strong&gt;. Some may argue that if you don't have highly sensitive information, it may be overkill to offer the 2FA. But any personal information could be considered sensitive.&lt;/p&gt;

&lt;p&gt;If you care about your users and their security, give them the option to enable the 2FA. Period.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Don't force the users to choose only one 2FA method
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.google.ca/landing/2step/" rel="noopener noreferrer"&gt;Google&lt;/a&gt;, &lt;a href="https://www.facebook.com/help/148233965247823" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;, &lt;a href="https://help.twitter.com/en/managing-your-account/two-factor-authentication" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;... they all offer simultaneous ways for 2FA: text message, authentication app and security key. More commonly, at least in a text message and authentication app, the security key seems to be set up only on certain services.&lt;/p&gt;

&lt;p&gt;But I've been surprised to see &lt;a href="https://help.etsy.com/hc/en-us/articles/115015569567-How-to-Make-Your-Account-More-Secure?segment=shopping" rel="noopener noreferrer"&gt;Etsy&lt;/a&gt;, even they use toggles on their UI, to force you to only choose one of the options. I'm not even sure if it was originally designed to work like that.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://support.bitly.com/hc/en-us/articles/230650187-What-is-2-step-verification-" rel="noopener noreferrer"&gt;Bit.ly&lt;/a&gt; and &lt;a href="https://partner.booking.com/en-gb/help/legal-security/what-2-factor-authentication-2fa" rel="noopener noreferrer"&gt;booking.com&lt;/a&gt; in other hand only allow you to use your phone as a 2FA device. So if you lose your phone and your email access, you could be screwed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiesx9m3rc29w9u9sbzvo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiesx9m3rc29w9u9sbzvo.jpg" alt="The verification code view on Booking.com" width="459" height="514"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://mailchimp.com/help/set-up-a-two-factor-authentication-app-at-login/" rel="noopener noreferrer"&gt;Mailchimp&lt;/a&gt; and &lt;a href="https://tumblr.zendesk.com/hc/en-us/articles/226270148-Two-factor-authentication" rel="noopener noreferrer"&gt;Tumblr&lt;/a&gt;, on the contrary, only offer 2FA using an authentication app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://zapier.com/help/account/manage-account/set-up-two-factor-authentication-for-your-zapier-account" rel="noopener noreferrer"&gt;Zapier&lt;/a&gt; has an awesome step by step 2FA setup, probably one of the best I found. They offer multiple complementary ways and specifically tell you "in the event you get locked out of your account and have lost both your authentication device and recovery codes". The user understands that providing his phone number is an additional way to ensure he/she can access his account in case he/she lost the other ways to connect to their web app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2wrn3dn80e5al4niams.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2wrn3dn80e5al4niams.jpg" alt="The two-factor step by step setup on Zapier" width="800" height="908"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Make the QR code an image
&lt;/h2&gt;

&lt;p&gt;I have been using &lt;a href="https://1password.com/" rel="noopener noreferrer"&gt;1Password&lt;/a&gt; for quite some time now and the modal that scans the QR code doesn't always find the QR code. In that case, I found myself drag and dropping the QR into that modal to be recognized. But it only works when the code is an image.&lt;/p&gt;

&lt;p&gt;I would recommend having it as a format image that can be saved / drag and dropped.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.reddit.com/" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt; for example doesn't have their QR code as an image. Fortunately, everyone offers the text version of the QR code that you can use in your authentication application.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Keep the code you send by email in the same format as requested in your app or website
&lt;/h2&gt;

&lt;p&gt;This one only happened to me once. It happened with Instagram.&lt;/p&gt;

&lt;p&gt;When &lt;a href="https://help.instagram.com/843785199163974" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; sends a "verification code" by SMS, they included a space. If you copy-paste that code where it's required, first the input doesn't want the space and the last digit is not included in your paste. It's an annoying issue that could be fixed easily!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvd5szzd22a7hrdtuxwgg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvd5szzd22a7hrdtuxwgg.jpg" alt="Instagram verification SMS code" width="443" height="163"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  5. Give the option to have recovery/backup codes
&lt;/h2&gt;

&lt;p&gt;Sounds weird when said at loud but a lot of websites don't offer backup/recovery codes when you enable the 2FA. This was a surprise for me at first, &lt;strong&gt;2FA means you will always have backup codes in case you lost access&lt;/strong&gt; to your phone, email or the app you use to generate the random number. Nowadays, some websites don't offer that option. I tend to be really careful with those.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://help.kickstarter.com/hc/en-us/articles/115005127094-How-can-I-enable-two-factor-authentication-" rel="noopener noreferrer"&gt;Kickstarter&lt;/a&gt; and &lt;a href="https://wpengine.com/support/multi-factor-authentication/" rel="noopener noreferrer"&gt;WPEngine&lt;/a&gt; are examples of websites that don't offer you any recovery/backup codes. I hope they could improve that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa02hke47pe988sp5pzqq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa02hke47pe988sp5pzqq.jpg" alt="The Kickstarter security modal" width="476" height="387"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  6. Always give the option to download the recovery codes
&lt;/h2&gt;

&lt;p&gt;Most of the websites propose to copy the recovery codes. This is not the best option.&lt;/p&gt;

&lt;p&gt;It's nice to have it, sure, but it's not enough. I personally store all my recovery codes in multiple places: one is the &lt;a href="https://www.dropbox.com/features/security/vault" rel="noopener noreferrer"&gt;vault from Dropbox&lt;/a&gt;. Having just to drag and paste a simple text file is easy and fast.&lt;/p&gt;

&lt;p&gt;If you offer only the option to copy, then you could be forcing the user to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1) open the text editor&lt;/li&gt;
&lt;li&gt;2) paste the codes&lt;/li&gt;
&lt;li&gt;3) give a name&lt;/li&gt;
&lt;li&gt;4) save the file on your device
Technology is there to save user's time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://slack.com/intl/en-ca/help/articles/204509068-Set-up-two-factor-authentication" rel="noopener noreferrer"&gt;Slack&lt;/a&gt; for example allows you to "Print codes" but not download them. Why not? I have to generate a PDF instead of my simple text file. Not the best user experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fel0snkfa3tnk4eli0gmm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fel0snkfa3tnk4eli0gmm.jpg" alt="The Two-Factor Authentication Backup Codes modal on Slack" width="722" height="540"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  7. In the recovery code text file, always write which platform these codes are coming from
&lt;/h2&gt;

&lt;p&gt;Even Facebook can make mistakes and this one is important for me. Currently, if you download the recovery codes from Facebook, you open the file and you can't find any mention of Facebook or the name of the account. The file name &lt;code&gt;facebook_recovery_codes&lt;/code&gt; is helpful but in my opinion, not enough. &lt;strong&gt;The name of the account and the name of the platform should be a minimum.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And to make it more useful, adding the date when the codes were generated could also be added.&lt;/p&gt;

&lt;p&gt;Google which is a good example, uses your username in the name of the file, and also adds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SAVE YOUR BACKUP CODES
Keep these backup codes somewhere safe but accessible.

LIST OF CODES

(email@gmail.com)

* You can only use each backup code once.
* Need more? Visit https://g.co/2sv
* These codes were generated on: Date, 2021.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Allow the user to regenerate recovery/backup codes
&lt;/h2&gt;

&lt;p&gt;It's essential to give the user the ability to regenerate recovery codes. Some don't offer this useful option.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Offer more than one code (maybe?)
&lt;/h2&gt;

&lt;p&gt;This one is less important but I still wanted to mention a key difference in terms of recovery/backup codes.&lt;/p&gt;

&lt;p&gt;Most of the companies only offer one code vs a list of multiples codes that can be used. It's hard for me to defend one approach vs the other one. I just know that I feel better when I have more than one code. &lt;/p&gt;

&lt;h2&gt;
  
  
  About security keys
&lt;/h2&gt;

&lt;p&gt;Security keys are the less common way to secure your account. If you are a public figure or someone with a high level of responsibility, having a security key could give you a little bit more peace of mind. But for a normal user, it may be overkill. Nonetheless, I wanted to maximize the security of my accounts and recently bought the &lt;a href="https://store.google.com/ca/product/titan_security_key" rel="noopener noreferrer"&gt;Titan Security Key&lt;/a&gt; from Google. The USB version works on any computer and I use the Bluetooth version in case I'm on my iPhone or iPad.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1adhyfuedjc43klvzhmk.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1adhyfuedjc43klvzhmk.jpeg" alt="The box of the Titan Security Keys by Google" width="800" height="803"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;They both are not cheap, but security should be part of your "unlimited budget", the same as for food.&lt;/p&gt;

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

&lt;p&gt;I'm not a security expert and have limited knowledge in terms of security. But as a Software Engineer and particularly a user, I believe we have a long way ahead until most of the platforms implement all the best practices and features to ensure secure access for all users.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Recap:&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Offer two-factor authentication options&lt;/li&gt;
&lt;li&gt;Don't force the users to choose only one 2FA method&lt;/li&gt;
&lt;li&gt;Make the QR code an image&lt;/li&gt;
&lt;li&gt;Keep the code you send by email in the same format as requested in your app or website&lt;/li&gt;
&lt;li&gt;Give the option to have recovery/backup codes&lt;/li&gt;
&lt;li&gt;Always give the option to download the recovery codes&lt;/li&gt;
&lt;li&gt;In the recovery code text file, always write which platform these codes are coming from&lt;/li&gt;
&lt;li&gt;Allow the user to regenerate recovery/backup codes&lt;/li&gt;
&lt;li&gt;Offer more than one code (maybe?)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thanks for reading, I hope these suggestions would help you to have a better UX and improve your 2FA implementation.&lt;/p&gt;

&lt;p&gt;Feel free to ask me anything in the comments below!&lt;/p&gt;

</description>
      <category>security</category>
      <category>ux</category>
      <category>twofactor</category>
      <category>2fa</category>
    </item>
    <item>
      <title>How to deploy your Next.js app on Netlify using Github Actions</title>
      <dc:creator>David Dias</dc:creator>
      <pubDate>Thu, 21 Jan 2021 21:58:24 +0000</pubDate>
      <link>https://dev.to/thedaviddias/how-to-deploy-your-next-js-app-on-netlify-using-github-actions-14bn</link>
      <guid>https://dev.to/thedaviddias/how-to-deploy-your-next-js-app-on-netlify-using-github-actions-14bn</guid>
      <description>&lt;p&gt;I've recently spent some time working with Next.js projects. Once my projects are done, the next logical step is to deploy these apps to be accessible to the world.&lt;/p&gt;

&lt;p&gt;I have naturally used the &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel platform&lt;/a&gt;, which couldn't be easier to use and deploy your application with ease. Then I tried &lt;a href="https://aws.amazon.com/amplify/" rel="noopener noreferrer"&gt;AWS Amplify&lt;/a&gt;, which I particularly love but for now, requires you to use the &lt;a href="https://docs.amplify.aws/start/getting-started/hosting/q/integration/next" rel="noopener noreferrer"&gt;Serverless Framework&lt;/a&gt; if you want to benefit from Server Side Rendering (SSR) capabilities.&lt;/p&gt;

&lt;p&gt;Then, I remembered that Netlify has added support for Next.js, including dynamic routes, Preview Mode and more since November 2020. It was time for me to try it! But I also wanted to have a real CI/CD in place, to test my code and do more actions before deploying to Netlify. That's where Github Actions came to the rescue!&lt;/p&gt;

&lt;p&gt;I'm going to describe in this article, all the steps you need to take to deploy your Next.js application on Netlify using Github Actions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The full version of the project can be &lt;a href="https://github.com/thedaviddias/next-netlify-github-actions-starter" rel="noopener noreferrer"&gt;found on Github&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Create a new Next.js App and push it to Github
&lt;/h2&gt;

&lt;p&gt;As always, you need to have a recent version of Node and NPM installed on your machine. I personally recommend using &lt;code&gt;NVM&lt;/code&gt; since it simplifies having multiple active Node.js versions.&lt;/p&gt;

&lt;p&gt;To create a new Next.js project, type this command in your CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app name-of-your-app

&lt;span class="c"&gt;# move into the app's root directory&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/path-to-projects/name-of-your-app/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will install a new application using a basic Next.js boilerplate. Don't forget to move to your app root folder before launching any next commands.&lt;/p&gt;

&lt;p&gt;Once your Next.js project is locally created, you can create a new project on Github and push the code generated.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(For those you are new to coding, feel free to &lt;a href="https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-new-repository" rel="noopener noreferrer"&gt;follow these steps&lt;/a&gt; to create a new repository on Github.)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up your Netlify project
&lt;/h2&gt;

&lt;p&gt;There are 2 ways of creating a new Netlify project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating a project online &lt;a href="https://app.netlify.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Using the Netlify CLI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's use the CLI this time, I'm sure you already created a new project in the past using the Netlify interface.&lt;/p&gt;

&lt;p&gt;Let's start by installing &lt;code&gt;netlify-cli&lt;/code&gt; globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;netlify-cli &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then check if the installation succeeds, confirming with this command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Netlify account authentication
&lt;/h3&gt;

&lt;p&gt;Now you need to link your computer with your Netlify account. To authenticate with Netlify, you need to run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;netlify login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will open a new tab in your browser where you'll need to "Authorize your Application" and then grant access to Netlify CLI.&lt;/p&gt;

&lt;p&gt;In case you already logged in previously, the console will output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Already logged &lt;span class="k"&gt;in &lt;/span&gt;via netlify config on your machine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Netlify project creation
&lt;/h3&gt;

&lt;p&gt;Now that your CLI is authorized to communicate with your Netlify account, it's time to programmatically create a new project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# create a new Netlify site using the Netlify shortcut: ntl&lt;/span&gt;
ntl init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first question you are asked is if you want to connect this directory to an existing Netlify site or create &amp;amp; configure a new site. Choose &lt;strong&gt;Create &amp;amp; configure a new site&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3lfvvphd22o7itwliymi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3lfvvphd22o7itwliymi.jpg" alt="Connect to an existing directory or create and configure a new site" width="496" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then you have to choose your &lt;strong&gt;team&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo2pxn7nwxd8bsxe440vy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo2pxn7nwxd8bsxe440vy.jpg" alt="Question about the name of the team" width="528" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose the &lt;strong&gt;name of your application&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiaih9331d9wzvyxun64e.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiaih9331d9wzvyxun64e.jpg" alt="Screenshot of the CLI asking for the name of your application" width="669" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After entering the name of your project, the site is created and few URLs populated the CLI which gave you access to your admin URL, the URL of your site and the Site ID. Keep the site ID aside, you will need that number later on. &lt;/p&gt;

&lt;p&gt;For the next 3 questions (build, start and function), &lt;strong&gt;insert a space&lt;/strong&gt;. We are not going to directly use the NPM scripts, our Github actions will later trigger each command.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0bl7dmlmnq91fam6cnfy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0bl7dmlmnq91fam6cnfy.jpg" alt="Screenshot of the CLI with the build, start and function script command suggestion" width="660" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, automatically create a netlify.toml file, which we will edit later. If your respond no, you can still create that file manually at the root of your project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgjeo2l0ojuqu3papjrcy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgjeo2l0ojuqu3papjrcy.jpg" alt="Screenshot of the CLI asking to create a netlify.toml file" width="666" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you provided an answer to all the questions, your terminal should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flmupvfb8aj5n17rl6nyk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flmupvfb8aj5n17rl6nyk.jpg" alt="Screenshot of the CLI after all the questions are answered" width="672" height="589"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Updating our Netlify project
&lt;/h2&gt;

&lt;p&gt;It's now time to change some options on our Netlify project. Open directly your project on Netlify with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ntl open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdw42yr8q0qg5tnau04b9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdw42yr8q0qg5tnau04b9.jpg" alt="Screenshot of the Netlify project created" width="800" height="494"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;You should see that our production deployment failed. You don't have to worry, this is totally normal. We need to disable our automatic build because our Github Actions will take care of it.&lt;/p&gt;

&lt;p&gt;Go in your Settings &amp;gt; Build &amp;amp; deploy. Click on &lt;code&gt;Edit settings&lt;/code&gt; and &lt;code&gt;Stop builds&lt;/code&gt;. Save.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuzlpzxz6jnixwxdtwbsf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuzlpzxz6jnixwxdtwbsf.jpg" alt="Screenshot of the Build settings on Netlify" width="800" height="697"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just below, go to the &lt;code&gt;Deploy contexts&lt;/code&gt; section and select &lt;code&gt;None&lt;/code&gt; for the Deploy previews.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwb9npfwim3m3huk6sfmi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwb9npfwim3m3huk6sfmi.jpg" alt="Screenshot of the Deploy context section on Netlify" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't worry, like the build, we will create our preview URL using Github actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enable server-side rendering on Netlify
&lt;/h2&gt;

&lt;p&gt;If you have been using Next.js you are aware of the capability to do the server-side rendering. But usually, you will need to configure a Node server and that's something we don't want to have to deal with. Around October 2020, the Netlify team started working on &lt;code&gt;next-on-netlify&lt;/code&gt;, a utility to enable SSR in Next.js on Netlify. That's what we are going to use here.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(In case you are not interested in Github Actions and want to use Netlify to build your project, take a look at how to use the &lt;a href="https://github.com/netlify/netlify-plugin-nextjs" rel="noopener noreferrer"&gt;Next on Netlify Plugin&lt;/a&gt;. It directly wraps your Next.js app and doesn't need as much configuration as we are going to explain.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's start by installing our utility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; next-on-netlify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Set Next.js target to serverless
&lt;/h3&gt;

&lt;p&gt;We must build our Next.js app as a serverless app. Create a new &lt;code&gt;next.config.js&lt;/code&gt; file at the root of your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// next.config.js&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Target must be serverless&lt;/span&gt;
  &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;serverless&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;h3&gt;
  
  
  Add a post build hook
&lt;/h3&gt;

&lt;p&gt;We need to add a &lt;code&gt;postbuild&lt;/code&gt; command that is automatically triggered after our &lt;code&gt;build&lt;/code&gt; command finishes. &lt;code&gt;next-on-netlify&lt;/code&gt; does a lot of "magic" to copy and set up our Next.js app to be correctly hosted on Netlify.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"next-netlify-github-actions-starter"&lt;/span&gt;,
  &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"0.1.0"&lt;/span&gt;,
  &lt;span class="s2"&gt;"private"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
  &lt;span class="s2"&gt;"scripts"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"dev"&lt;/span&gt;: &lt;span class="s2"&gt;"next dev"&lt;/span&gt;,
    &lt;span class="s2"&gt;"build"&lt;/span&gt;: &lt;span class="s2"&gt;"next build"&lt;/span&gt;,
    &lt;span class="s2"&gt;"start"&lt;/span&gt;: &lt;span class="s2"&gt;"next start"&lt;/span&gt;,
    &lt;span class="s2"&gt;"postbuild"&lt;/span&gt;: &lt;span class="s2"&gt;"next-on-netlify"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  ...
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure Netlify
&lt;/h3&gt;

&lt;p&gt;Remember the file that was automatically created and called &lt;code&gt;netlify.toml&lt;/code&gt;? You can remove all the boilerplate and replace it with only this code (be careful in respecting the indentation):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[build]
  command   = ""
  functions = "out_functions"
  publish   = "out_publish"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Technically, when &lt;code&gt;next-on-netlify&lt;/code&gt; will run, it will take what is in these folders and host it on Netlify. &lt;strong&gt;&lt;em&gt;DO NOT CHANGE&lt;/em&gt;&lt;/strong&gt; the name of these folders as these are hardcoded into the utility.&lt;/p&gt;

&lt;p&gt;Don't forget to add these line to your &lt;code&gt;.gitignore&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Netlify build
out_*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can commit your files. Let's work now on the Github Actions configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Github Actions configuration
&lt;/h2&gt;

&lt;p&gt;The netlify configuration is now done, all dependencies installed, it's time to configure our Github actions which will test, build and deploy our Next.js application to Netlify. But before that, we need to set up some Github secrets that we will need in our GH Actions.&lt;/p&gt;

&lt;p&gt;Go to your &lt;code&gt;Github project &amp;gt; Settings &amp;gt; Secrets &amp;gt; New repository secret&lt;/code&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Actions secret name&lt;/th&gt;
&lt;th&gt;Comments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NETLIFY_AUTH_TOKEN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Request your token &lt;a href="https://app.netlify.com/user/applications#personal-access-tokens" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NETLIFY_SITE_ID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The site to where deploy your site (get it from the API ID on your Site Settings)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnhyz9ipggiss8l2pfw4w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnhyz9ipggiss8l2pfw4w.jpg" alt="Screenshot of the Actions secrets page on Github" width="800" height="523"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Create a new file called &lt;code&gt;main.yml&lt;/code&gt; inside &lt;code&gt;.github/workflows&lt;/code&gt;. Copy-paste the following code and read the explanation of it after this snippet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Main workflow&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;opened&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;synchronize&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;reopened&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

      &lt;span class="c1"&gt;# Cache node modules and next folder&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;📬 Caching&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/cache@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;**/node_modules&lt;/span&gt;
            &lt;span class="s"&gt;${{ github.workspace }}/.next/cache&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ runner.os }}-modules-${{ hashFiles('**/package-lock.json') }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use Node.js 14.x&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;14.x&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;🧰 Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run install&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;📦 Build project&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build --if-present&lt;/span&gt;

      &lt;span class="c1"&gt;# - name: 🧹 Run lint&lt;/span&gt;
      &lt;span class="c1"&gt;#   run: npm run lint&lt;/span&gt;

      &lt;span class="c1"&gt;# - name: 🐛 Run tests&lt;/span&gt;
      &lt;span class="c1"&gt;#   run: npm run test&lt;/span&gt;

      &lt;span class="c1"&gt;# Deploy to Netlify with a personalized message&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;🚀 Deploy to Netlify&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy-netlify&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;netlify/actions/cli@master&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;NETLIFY_AUTH_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NETLIFY_AUTH_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;NETLIFY_SITE_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NETLIFY_SITE_ID }}&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy -m 'v${{ steps.package-version.outputs.current-version}} ・ ${{ github.head_ref }}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Detailed explanation of the main workflow file
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Give a name&lt;/em&gt;&lt;/strong&gt; to your Github action&lt;/li&gt;
&lt;li&gt;Choose which &lt;strong&gt;&lt;em&gt;type of the event&lt;/em&gt;&lt;/strong&gt; should trigger this action, you can use push instead of pull_request, it's up to you.&lt;/li&gt;
&lt;li&gt;Specify on &lt;strong&gt;&lt;em&gt;which system&lt;/em&gt;&lt;/strong&gt; this action should be launched, I choose the latest version of Ubuntu (Linux).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Checkout your code&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Cache your node modules&lt;/em&gt;&lt;/strong&gt; and the .next/cache folder. When you will first run this action, it will take some time. On the second launch, the action will take the modules that exist in the cache and will then proceed way faster.&lt;/li&gt;
&lt;li&gt;Specify the &lt;strong&gt;&lt;em&gt;version of Node&lt;/em&gt;&lt;/strong&gt; you want to use, in my case, I choose the most recent version of Node 14th.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Install the dependencies&lt;/em&gt;&lt;/strong&gt; of your project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Build your project&lt;/em&gt;&lt;/strong&gt;. Remember that after the build, the post-build command will be launch. This is what you should see in the &lt;code&gt;build&lt;/code&gt; logs in your Github Action tab:
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvgv3g9u9wuo1besc5v2d.jpg" alt="Screenshot of the build-in Github Action" width="800" height="818"&gt;
&lt;/li&gt;
&lt;li&gt;I added lint and test commands, which I commented. You can use these to trigger ESLint, Jest (even Cypress) or any other plugin that ensures your code doesn't have any issue.&lt;/li&gt;
&lt;li&gt;Finally, we trigger the Netlify deployment to deploy our Next.js app to Netlify. 🎉&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn6i27u3pwq1l3am12u8n.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn6i27u3pwq1l3am12u8n.jpg" alt="Screenshot of all Github actions" width="730" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You may have seen an argument passed to the Netlify deploy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy -m '${{ github.head_ref }}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will add a message (more specifically your branch name) for each Deploy Preview, a way to keep track of which PR generated which Deploy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd0f20hzeayxu0hnqt6ry.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd0f20hzeayxu0hnqt6ry.jpg" alt="Screenshot of the Deploy page on Netlify" width="800" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the same deploy page, you can click on the Deploy Preview and access your app using the preview URL.&lt;/p&gt;

&lt;p&gt;A better way would be to use another task to automatically populate your pull request with the log and preview URL. At the end of your file, add this action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Publish the inspect and preview link to the PR&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;👓 Netlify Preview URL&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unsplash/comment-on-pr@master&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
    &lt;span class="na"&gt;OUTPUT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;pull&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;request&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;being&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;automatically&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;deployed&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Netlify.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;🔍&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Inspect:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.deploy-netlify.outputs.NETLIFY_LOGS_URL&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;✅&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Preview:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.deploy-netlify.outputs.NETLIFY_URL&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.OUTPUT }}&lt;/span&gt;
    &lt;span class="na"&gt;check_for_duplicate_msg&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will automatically create a comment in your PR.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4m7fz8scb7knsclnb5cj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4m7fz8scb7knsclnb5cj.jpg" alt="Screenshot of the PR on Github specifying the link to the logs and preview deploy URL" width="800" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe3frz0hz0wpucyx9pvwe.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe3frz0hz0wpucyx9pvwe.gif" alt="Rocky Balboa pulling with his arms towards the sky like a winner" width="480" height="192"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If you are still reading this, congrats! You have succeeded in deploying a fully enabled Next.JS application to Netlify using Github Actions!&lt;/p&gt;

&lt;p&gt;The next step for you now will be to add some linting rules and tests to ensure that you are sending to Netlify, an app that works perfectly!&lt;/p&gt;

&lt;p&gt;Feel free to &lt;a href="https://github.com/thedaviddias/next-netlify-github-actions-starter" rel="noopener noreferrer"&gt;download or fork the &lt;code&gt;next-netlify-github-actions-starter&lt;/code&gt;&lt;/a&gt;, open an issue if you find any problem or send me any suggestion to make it better!&lt;/p&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.netlify.com/blog/2020/11/30/how-to-deploy-next.js-sites-to-netlify/" rel="noopener noreferrer"&gt;How to Deploy Next.js Sites to Netlify&lt;/a&gt; by Jason Lengstorf&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.netlify.com/blog/2020/10/27/preview-mode-for-next.js-now-fully-supported-on-netlify/" rel="noopener noreferrer"&gt;Preview Mode for Next.js now fully supported on Netlify&lt;/a&gt; by Cassidy Williams&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.netlify.com/blog/2020/12/07/announcing-one-click-install-next.js-build-plugin-on-netlify/" rel="noopener noreferrer"&gt;Announcing one-click install Next.js Build Plugin on Netlify&lt;/a&gt; by Cassidy Williams&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>netlify</category>
      <category>nextjs</category>
      <category>github</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
