<?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: Anchor</title>
    <description>The latest articles on DEV Community by Anchor (@anchordotdev).</description>
    <link>https://dev.to/anchordotdev</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%2Forganization%2Fprofile_image%2F8549%2F17564304-2c41-4bef-a855-a23237ddd71c.jpg</url>
      <title>DEV Community: Anchor</title>
      <link>https://dev.to/anchordotdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anchordotdev"/>
    <language>en</language>
    <item>
      <title>Developing CLIs</title>
      <dc:creator>Wesley Beary</dc:creator>
      <pubDate>Mon, 12 Aug 2024 19:00:00 +0000</pubDate>
      <link>https://dev.to/anchordotdev/developing-clis-o14</link>
      <guid>https://dev.to/anchordotdev/developing-clis-o14</guid>
      <description>&lt;p&gt;Building CLI features often boils down to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Release new API endpoint(s).&lt;/li&gt;
&lt;li&gt;Build new CLI actions that need the API changes.&lt;/li&gt;
&lt;li&gt;Realize mistakes were made in the API you just released.&lt;/li&gt;
&lt;li&gt;Try to fix the API for this feature without creating more problems in the future.&lt;/li&gt;
&lt;li&gt;Try to remember what you were trying to achieve in the CLI and then actually achieve it.  &lt;/li&gt;
&lt;li&gt;GOTO: realize mistakes were made.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each step requires the one before and oops we've reinvented waterfall project management. You get worn down by the pain trying to gracefully pave over mistakes until you limp to functional, but bow out well before exceptional. And don’t get me started on maintaining the resulting cluster of ad-hoc “fixes” and warts.&lt;/p&gt;

&lt;p&gt;Been there, done that. We knew we needed to move past the waterfall-ish approach.&lt;/p&gt;

&lt;p&gt;Here is the story of how we got there and some of the tools that helped along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Off to a Sketchy Start
&lt;/h2&gt;

&lt;p&gt;We wanted cheap, fast iteration until we understood the feature, and only then commit to expensive implementation and long-term support. As a small team, I was often doing this process end to end, and wanted to focus on each part in turn. We wanted to fake implementation parts until we felt confident enough to make it.&lt;/p&gt;

&lt;p&gt;Getting back to the process, it starts with proposing features. We wanted to get out of the abstract, but not if it meant half-baked implementation. We faked it with "sketches", inspired by the Google Docs CLI sketch approach that Github describes &lt;a href="https://www.youtube.com/watch?v=zsjeZZVAk1E&amp;amp;t=685s" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately, static sketches didn't quite give us the feedback we wanted. Our CLI changes output over time, more like animation than a drawing. To achieve higher fidelity, I wrote little Ruby programs to take basic inputs and respond by printing appropriate canned responses.&lt;/p&gt;

&lt;p&gt;Since then we've found an even better way to capture animated CLI output, but to explain that requires a little detour.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do You Even Test?
&lt;/h2&gt;

&lt;p&gt;As we started to flesh out our CLI, we also wanted to test edge cases and detect regressions. I surveyed public &lt;a href="https://cobra.dev/" rel="noopener noreferrer"&gt;cobra&lt;/a&gt;/&lt;a href="https://github.com/charmbracelet/bubbletea" rel="noopener noreferrer"&gt;bubbletea&lt;/a&gt; based CLIs to look for ideas, and found frustratingly few tests. Then we stumbled upon Charm's &lt;a href="https://charm.sh/blog/teatest/" rel="noopener noreferrer"&gt;teatest&lt;/a&gt; which gave us a starting point.&lt;/p&gt;

&lt;p&gt;Teatest focuses on golden tests, capturing a known good output and then asserting that future outputs continue to match it. Which brought us back, once again, to high fidelity capture of animated CLI outputs. Teatest gave us the great idea of a frame-based solution, like a flipbook, which we have built upon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;─── SigninHeader ───────────────────────────────────────────────────────────────
# Signin To Your CLI Account `cli auth signin`
─── SigninInput --──────────────────────────────────────────────────────────────
# Signin To Your CLI Account `cli auth signin`
    ? What is your username?
    ? user
─── SigninInput ────────────────────────────────────────────────────────────────
# Signin To Your CLI Account `cli auth signin`
    * Signing in to your CLI account… ⠋
─── SigninInput ────────────────────────────────────────────────────────────────
# Signin To Your CLI Account `cli auth signin`
    * Signed in to your CLI account: user@example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simplified example shows what a golden output might look like for a basic authorization command. The horizontal lines delineate frames, with labels indicating the active model. Taken together we get a high fidelity capture of output even as lines are added, removed, or replaced.&lt;/p&gt;

&lt;p&gt;We use a flag in our test suite to update files with the golden outputs, and otherwise the tests fail if the output doesn't match the files. This keeps us aware of output changes and facilitates PR reviews by allowing us to understand what the output should look like and if it has changed. We like it so much that we plan to replace our sketch programs with golden style output in Github style google docs so we can capture both animation and style ideas.&lt;/p&gt;

&lt;p&gt;With our once and future sketches in hand, let's return to getting started with new API endpoints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing API and CLI Together
&lt;/h2&gt;

&lt;p&gt;We work on the API and CLI simultaneously, because the best designs for these grow out of tight integration. We are able to do this, while still avoiding the perils of waterfall, by iterating on designs in cheaper contexts and waiting to implement until the requirements solidify. For our APIs, this means sketching with &lt;a href="https://www.openapis.org/" rel="noopener noreferrer"&gt;OpenAPI&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openapi: 3.1.0
info:
  contact:
    email: contact@example.com
  description: An example API.
  title: Example API
  version: 0.0.1
servers:
  - url: https://api.example.com
tags:
  - description: account operations
    name: account
paths:
  '/v0/auth/signin':
    post:
      description: Signin to CLI.
      operationId: auth_signin
      responses:
        '200':
          content:
            'application/json':
              schema:
                additionalProperties: false
                properties:
                  email:
                    description: Email address for authenticated user.
                    example: username@example.com
                    type: string
                required:
                  - email
                type: object
          description: Successful signin.
      summary: Signin to CLI.
      tags:
        - account
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simplified example shows what a schema might look like for a basic authorization command. We use the &lt;a href="https://docs.stoplight.io/docs/spectral/674b27b261c3c-overview" rel="noopener noreferrer"&gt;spectral&lt;/a&gt; linter to simplify working on these files.&lt;/p&gt;

&lt;p&gt;With a sketch in hand, we then use &lt;a href="https://docs.stoplight.io/docs/prism/674b27b261c3c-prism-overview" rel="noopener noreferrer"&gt;prism&lt;/a&gt; as a mock API server while we implement the CLI. When we inevitably realize mistakes were made, we can just tweak the spec and get back to our CLI iteration. Working at this high level allows us to evolve the API and CLI together and defer costly implementation until we have better knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing APIs
&lt;/h2&gt;

&lt;p&gt;We also lean into our OpenAPI spec to keep us honest during implementation using &lt;a href="https://github.com/interagent/committee" rel="noopener noreferrer"&gt;committee&lt;/a&gt;. &lt;code&gt;assert_schema_conform&lt;/code&gt; tests alignment and the middleware notifies us of any live discrepancies. These combine to allow for red green implementation while protecting us from regressions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing with Mocks and Proxies
&lt;/h2&gt;

&lt;p&gt;To round things out, our test suite uses flags to run prism in either mock or proxy mode. By using flags we can focus on writing just one kind of test, though it does mean we skip some tests in one mode or the other. We use mock tests for their speed and on Windows and macOS where our full stack doesn't run in CI. Our proxy tests let us run tests against our entire stack just by adding a flag, making it easy to run end to end testing whenever we deem it necessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pulling it All Together
&lt;/h2&gt;

&lt;p&gt;Sketches and specs help us iterate past the abstract without having to get bogged down in implementation. Then mocks and proxies help us ensure the implementations match the sketches. By continuing to iterate our process, each feature causes less pain, which we have deeply appreciated while building the teams experience we will deliver later this month.&lt;/p&gt;

&lt;p&gt;We will keep iterating on our process, I hope you learned something from it and I would love to learn from you. What have you tried, where are you proud and what remains frustrating?&lt;/p&gt;

</description>
      <category>cli</category>
      <category>api</category>
      <category>go</category>
    </item>
    <item>
      <title>HTTPS on Localhost with Next.js</title>
      <dc:creator>Ben Burkert</dc:creator>
      <pubDate>Mon, 29 Apr 2024 16:04:00 +0000</pubDate>
      <link>https://dev.to/anchordotdev/https-on-localhost-with-nextjs-38g8</link>
      <guid>https://dev.to/anchordotdev/https-on-localhost-with-nextjs-38g8</guid>
      <description>&lt;p&gt;Next.js is a popular framework for building web applications with great development support and tooling. However, its local development story has a plot hole: HTTPS support. While the next dev command has a &lt;code&gt;--experimental-https&lt;/code&gt; flag to &lt;a href="https://nextjs.org/docs/pages/api-reference/next-cli#https-for-local-development"&gt;enable HTTPS locally&lt;/a&gt;, it’s rather limited.&lt;/p&gt;

&lt;p&gt;Anchor’s new &lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; service fills this hole and even works with Docker containers. This article will explain what &lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; is, how it compares to Next.js’ experimental HTTPS flag, and how to configure your Next.js application to work with &lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is lcl.host?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; is an easy way to enable HTTPS in local development environments, which improves the security of the development process, ensures feature parity between development and production environments, and enables features like CORS that behave differently on localhost.&lt;/p&gt;

&lt;p&gt;There are multiple ways to use HTTPS on a local machine. You need to get a certificate for your server, renew it when it expires, and ensure your clients trust the CA that issued that certificate. If you get a certificate from a public CA, your clients automatically trust it, but your development server must be public, too. If you set up a local CA, your server can be private, but your clients need updates to trust your CA.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; takes care of all this for you by providing a CA for development, ensuring your browsers and clients trust this CA, issuing certificates for your apps, and renewing them when they expire.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the Benefits of Using lcl.host over Next.js’ Experimental HTTPS Flag?
&lt;/h2&gt;

&lt;p&gt;Next.js offers an experimental flag that enables HTTPS locally. While &lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; requires a bit more setup, it also brings several benefits over the flag.&lt;/p&gt;

&lt;h3&gt;
  
  
  lcl.host Works With All Next.js Commands
&lt;/h3&gt;

&lt;p&gt;To use the experimental HTTPS support, add the &lt;code&gt;--experimental-https&lt;/code&gt; flag every time you run &lt;code&gt;next dev&lt;/code&gt; command.&lt;br&gt;
With &lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; you can use all &lt;code&gt;next&lt;/code&gt; commands without a flag, and HTTPS works transparently with them.&lt;/p&gt;
&lt;h3&gt;
  
  
  lcl.host Works With HTTP and HTTPS
&lt;/h3&gt;

&lt;p&gt;While the experimental HTTPS flag only listens on HTTPS, &lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; allows using HTTP and HTTPS simultaneously, so you can switch without restarting your server.&lt;/p&gt;
&lt;h3&gt;
  
  
  lcl.host Works With Docker Containers
&lt;/h3&gt;

&lt;p&gt;The experimental HTTPS flag relies on &lt;a href="https://github.com/FiloSottile/mkcert"&gt;&lt;code&gt;mkcert&lt;/code&gt;&lt;/a&gt;, designed for a single development system. If you run a Docker container, the flag won’t configure your local browser to trust its certificate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; configures your browser on your system to trust the certificates in all containers you run locally.&lt;/p&gt;
&lt;h3&gt;
  
  
  lcl.host Works With Subdomains
&lt;/h3&gt;

&lt;p&gt;Experimental HTTPS only works with &lt;code&gt;localhost&lt;/code&gt;; if you have multiple applications, they all run on &lt;code&gt;localhost&lt;/code&gt; with different ports. &lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; doesn’t limit you to &lt;code&gt;https://localhost:&amp;lt;PORT&amp;gt;/&lt;/code&gt;; you can use any subdomain of &lt;code&gt;lcl.host&lt;/code&gt;, allowing you to run multiple apps simultaneously.&lt;/p&gt;
&lt;h3&gt;
  
  
  lcl.host Renews Certificates Automatically
&lt;/h3&gt;

&lt;p&gt;Experimental HTTPS might not take expired certificates into account. &lt;/p&gt;

&lt;p&gt;&lt;a href="//lcl.host"&gt;lcl.host&lt;/a&gt; handles automatic certificate renewal for you.&lt;/p&gt;
&lt;h3&gt;
  
  
  lcl.host Integrates With the Experimental HTTPS Flag
&lt;/h3&gt;

&lt;p&gt;The experimental HTTPS flag works with existing certificates to import the certificates generated by &lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; with the &lt;code&gt;--experimental-https-key&lt;/code&gt; and &lt;code&gt;--experimental-https-cert&lt;/code&gt; flags.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to Use lcl.host in a Next.js Project?
&lt;/h2&gt;

&lt;p&gt;Now that you understand what &lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; can do for you, the next step is to see how to integrate it with a Next.js app.&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/"&gt;Git&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  1. Installing the Anchor CLI
&lt;/h3&gt;

&lt;p&gt;First, you must install the Anchor CLI; this will handle the &lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; setup for your project.&lt;/p&gt;

&lt;p&gt;With Homebrew (MacOS and Linux):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew install anchordotdev/tap/anchor&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With Chocolatey (Windows):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;choco install anchor --version=0.0.22&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Build from source with Go:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;go install github.com/anchordotdev/cli/cmd/anchor@latest&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Using Anchor’s Next.js Starter Template
&lt;/h3&gt;

&lt;p&gt;For a new project, you can &lt;a href="https://github.com/anchordotdev/nextjs-lclhost-starter"&gt;use the Next.js-lcl.host starter template&lt;/a&gt; provided by Anchor. It comes preinstalled with dependencies for automatic certificate renewal and an update &lt;code&gt;next.config.mjs&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;You can clone it from GitHub with this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone https://github.com/anchordotdev/nextjs-lclhost-starter.git&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Using this template, you can skip to step 5.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  3. Installing Dependencies
&lt;/h3&gt;

&lt;p&gt;For the automatic certificate renewal, you need the latest &lt;a href="https://www.npmjs.com/package/anchor-pki"&gt;anchor-pki&lt;/a&gt; package. Install it as a development dependency with the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i anchor-pki -D&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; works without this package, but when your certificates expire you must manually renew them.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. Updating the Next.js Configuration
&lt;/h3&gt;

&lt;p&gt;Now, you must tell Next.js to use the anchor-pki package every time you run your app. To do so, update the content of your &lt;code&gt;next.config.mjs&lt;/code&gt; file:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;autoCert&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;anchor-pki/auto-cert/integrations/next&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;withAutoCert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;autoCert&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;enabledEnv&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;development&lt;/span&gt;&lt;span class="dl"&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;nextConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// Your configurations&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;withAutoCert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can configure your Next.js app as usual; just ensure the config object is wrapped in the &lt;code&gt;withAutoCert()&lt;/code&gt; call before exporting it.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Connecting the Project with lcl.host
&lt;/h3&gt;

&lt;p&gt;To make your project available via &lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt;, open the project directory in a shell and run the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;anchor lcl&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After the command completes, you should see a URL to a guide for the automatic renewal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| Next Steps
  | Now that you have local HTTPS setup, let's automate certificate provisioning
  | so you never have to manually provision future certificates again.
  | 
  | We've generated an Anchor.dev setup guide for your application with
  | instructions for automating certificate provisioning inside your
  application.
  - Opened https://anchor.dev/&amp;lt;ACCOUNT&amp;gt;/services/&amp;lt;APP_NAME&amp;gt;/guide.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open this guide in your browser, then skip to the second step, as we already performed the first two here.&lt;/p&gt;

&lt;p&gt;Click the “Generate new tokens” button, as seen in Figure 1, and copy the tokens and other environment variables into a new &lt;code&gt;.env.local&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F35w6108yog9534dw9w8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F35w6108yog9534dw9w8n.png" alt="generate-new-tokens-button" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The content of the env file should look similar to this:&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="nv"&gt;ACME_KID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;aae…zWD
&lt;span class="nv"&gt;ACME_HMAC_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;72D…dMr
&lt;span class="nv"&gt;ACME_DIRECTORY_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'https://anchor.dev/&amp;lt;ACCOUNT&amp;gt;/localhost/x509/ca/acme'&lt;/span&gt;
&lt;span class="nv"&gt;ACME_CONTACT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;ACCOUNT_EMAIL&amp;gt;+&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ACME_KID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;ACME_ALLOW_IDENTIFIERS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;APP_NAME&amp;gt;.lcl.host,&amp;lt;APP_NAME&amp;gt;.localhost"&lt;/span&gt;
&lt;span class="nv"&gt;HTTPS_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;RANDOM_PORT&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next.js will use the &lt;code&gt;.env.local&lt;/code&gt; file to set up environment variables before starting the web server. &lt;/p&gt;

&lt;h3&gt;
  
  
  6. Testing the Project
&lt;/h3&gt;

&lt;p&gt;Finally, to test the whole setup, you can start the development server with this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm run dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If everything goes well, you should get an output similar to this:&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;AutoCert] Starting auto-cert proxy ...
&lt;span class="o"&gt;[&lt;/span&gt;anchor-pki] The &lt;span class="s1"&gt;'sni-callback'&lt;/span&gt; Configuration instance is enabled
&lt;span class="o"&gt;[&lt;/span&gt;AutoCert] Listening on https://&amp;lt;APP_NAME&amp;gt;.lcl.host:44356 -&amp;gt; http://127.0.0.1:3000
&lt;span class="o"&gt;[&lt;/span&gt;AutoCert] Listening on https://&amp;lt;APP_NAME&amp;gt;.localhost:44356 -&amp;gt; http://127.0.0.1:3000
&lt;span class="o"&gt;[&lt;/span&gt;anchor-pki] No Terms of Service exist so agreed : &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;anchor-pki] No Terms of Service exist so agreed : &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;anchor-pki] Certificate &lt;span class="k"&gt;for&lt;/span&gt; &amp;lt;APP_NAME&amp;gt;.lcl.host provisioned.
&lt;span class="o"&gt;[&lt;/span&gt;anchor-pki] Certificate &lt;span class="k"&gt;for&lt;/span&gt; &amp;lt;APP_NAME&amp;gt;.lcl.host cached &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;tmp/acme&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the output tells, you can now access your app via two HTTPS-enabled URLs.&lt;br&gt;
If you get this error instead, it indicates a missing or incomplete &lt;code&gt;.env.local&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;[AutoCert] HTTPS_PORT is not set, assuming 4333
/path/to/your/project/node_modules/anchor-pki/src/auto-cert/configuration.js:185
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Return to step 5 and double-check you didn’t miss any environment variables.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Next.js has a nifty HTTPS feature, which is nice for quickly testing an app on your local machine. However, its tricky to use with Docker or multiple applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; is a complete solution for HTTPS-enabled development environments. It handles automatic certificate renewal and works transparently with several setups, including Docker, multiple local applications, and all Next.js commands.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/anchordotdev/cli"&gt;Anchor CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anchordotdev/nextjs-lclhost-starter"&gt;Next.js lcl.host starter template&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nextjs</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Squashing Mixed Content in Development with lcl.host</title>
      <dc:creator>Ben Burkert</dc:creator>
      <pubDate>Fri, 22 Mar 2024 17:24:13 +0000</pubDate>
      <link>https://dev.to/anchordotdev/squashing-mixed-content-in-development-with-lclhost-17lj</link>
      <guid>https://dev.to/anchordotdev/squashing-mixed-content-in-development-with-lclhost-17lj</guid>
      <description>&lt;p&gt;&lt;a href="https://web.dev/articles/what-is-mixed-content"&gt;Mixed content&lt;/a&gt; occurs when a webpage served over HTTPS loads a resource over HTTP. Browsers block these mixed content resources to protect your security, but blocked resources can break your pages. These bugs often slip through to production because browsers specifically allow mixed content on &lt;code&gt;http://localhost&lt;/code&gt; pages. Switching to HTTPS in local development will make our browser block mixed content and behave the same for the local and deployed version.&lt;/p&gt;

&lt;p&gt;Getting HTTPS setup and working with an app in local development is tricky. There were two options: acquire a publicly-trusted certificate from a CA, or make your own self-signed certificate from the command line. Neither of these options are simple, that's why most developers skip HTTPS in their development environment. But &lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; now makes this quick and easy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lcl.host/"&gt;lcl.host&lt;/a&gt; is a free developer tool from &lt;a href="https://anchor.dev/"&gt;Anchor.dev&lt;/a&gt; to setup a local HTTPS development environment in minutes. It combines the best parts of both public CA certificates and self-signed certificates, and it's built for novice and expert web developers alike. &lt;a href="https://anchor.dev/blog/introducing-lcl-host"&gt;Read more about how lcl.host works on the Anchor blog.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we will look at mixed content issues in practice with an example app which attempts to load a script asset over HTTP. Our browser will allow the script to load via &lt;code&gt;http://localhost&lt;/code&gt; but will block the script over HTTPS, just as it does with deployed apps. &lt;strong&gt;Using HTTPS in local development let's us catch mixed content warnings and errors before we deploy and cause issues for users.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Mixed Content Example App
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/anchordotdev/mixed-content-example"&gt;&lt;code&gt;anchordotdev/mixed-content-example&lt;/code&gt;&lt;/a&gt; is a nodejs app that triggers a mixed content error when served over HTTPS. We'll start by setting up the app and running it with just HTTP, which won't trigger any errors at all.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/anchordotdev/mixed-content-example
$ cd mixed-content-example
$ npm install
$ node ./index.js
mixed-content-example app over HTTP: http://localhost:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Browse to &lt;a href="http://localhost:3000/"&gt;http://localhost:3000/&lt;/a&gt; and you'll see "INSECURE SCRIPT LOADED AND RUN!!!", demonstrating that the insecure script loaded without any errors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv0x2pc6eyc9f1zryye7g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv0x2pc6eyc9f1zryye7g.png" alt="insecure mixed content allowed" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This script will always be insecure because it's always served over HTTP, yet our browser allowed it through! Next let's setup and use lcl.host to serve the page over HTTPS and secure our page.&lt;/p&gt;

&lt;h3&gt;
  
  
  lcl.host
&lt;/h3&gt;

&lt;p&gt;Setting up local HTTPS used to be a pain, but lcl.host makes it easy: install the CLI, run &lt;code&gt;anchor lcl&lt;/code&gt;, and work through the guided steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ brew install anchordotdev/tap/anchor
$ anchor lcl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For the example, we use the suggested values for all the prompts.&lt;/strong&gt; Once you are done, restart the app, and you'll see it is now listening on both &lt;strong&gt;HTTP and HTTPS&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ node ./index.js
mixed-content-example app over HTTP: http://localhost:3000
mixed-content-example app over HTTPS: https://mixed-content-example.lcl.host:44375
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now open the HTTPS version in your browser, and &lt;strong&gt;be sure to use the port number returned when you run the app, which may differ from what we depict here.&lt;/strong&gt; Notice this time the "INSECURE" message doesn't appear, because your browser blocked the script for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffns55lxe94rolaq4pw6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffns55lxe94rolaq4pw6c.png" alt="secure mixed content blocked" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we look in the devtools console, we also can see there is now a "Mixed Content" error for the insecure &lt;code&gt;simple-example.js&lt;/code&gt; script.&lt;/p&gt;

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

&lt;p&gt;Working through this example helped us reproduce mixed content errors and catch them in our dev tools console. You can use lcl.host to catch mixed content bugs in all your web applications too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real World Apps
&lt;/h3&gt;

&lt;p&gt;Using lcl.host with real development apps works the same as the example: run &lt;code&gt;anchor lcl&lt;/code&gt; in the project directory and follow the guide. &lt;a href="https://anchor.dev/docs/lcl-host/why-lcl#when-do-i-need-https-locally"&gt;Check out the lcl.host docs to learn more about other issues that local HTTPS helps mitigate.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>https</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
