<?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: Peace Sandy</title>
    <description>The latest articles on DEV Community by Peace Sandy (@peacesandy).</description>
    <link>https://dev.to/peacesandy</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%2F1037373%2Fc395b250-65be-42ef-959a-477af08e62e3.jpeg</url>
      <title>DEV Community: Peace Sandy</title>
      <link>https://dev.to/peacesandy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/peacesandy"/>
    <language>en</language>
    <item>
      <title>Building a Multi-Environment Web App on App Platform</title>
      <dc:creator>Peace Sandy</dc:creator>
      <pubDate>Wed, 29 Apr 2026 11:09:05 +0000</pubDate>
      <link>https://dev.to/peacesandy/building-a-multi-environment-web-app-on-app-platform-4nce</link>
      <guid>https://dev.to/peacesandy/building-a-multi-environment-web-app-on-app-platform-4nce</guid>
      <description>&lt;p&gt;Deploying straight to production is one of the most common mistakes developers make early in their careers. One environment, one URL, and one quiet hope that nothing will break. It works until it doesn't. &lt;/p&gt;

&lt;p&gt;A single bad push on a Friday afternoon can leave a client's homepage blank, with no staging environment to catch the issue and no safe place to roll back. Deploying without a safety net isn't a workflow; it's a risk.&lt;/p&gt;

&lt;p&gt;Many developers stay in this pattern longer than they should. A single live environment feels faster to maintain. But as applications scale, the approach becomes fragile. Bugs reach users before they are caught. &lt;/p&gt;

&lt;p&gt;Multi-Environment architecture solves this. By separating your application into distinct staging and production deployments, you create a safe layer where changes are validated before they affect real users. &lt;/p&gt;

&lt;p&gt;Each environment runs the same codebase with different configurations, so what you test in staging is exactly what ships to production, no surprises.&lt;/p&gt;

&lt;p&gt;In this tutorial, you will build a Next.js application and deploy it across two fully independent environments on &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; App Platform, a managed cloud service that builds and deploys apps directly from a GitHub repository.  &lt;/p&gt;

&lt;p&gt;You will configure environment variables to control how the app behaves in each environment, set up a Git branch strategy that maps staging and production to separate deployments, and enable autodeploy so that every push automatically triggers a rebuild. &lt;/p&gt;

&lt;p&gt;By the end, you will have a working multi-environment setup and a repeatable promotion workflow that lets you ship with confidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To complete this tutorial, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Node.js v18&lt;/strong&gt; or higher is installed on your machine, including npm, which comes bundled with it. You can check your versions by running &lt;code&gt;node -v&lt;/code&gt; and &lt;code&gt;npm -v&lt;/code&gt; in your terminal. If you need to install Node.js, follow How To Install Node.js and Create a Local Development Environment for your system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Git&lt;/strong&gt; is installed on your local machine. Run &lt;code&gt;git --version&lt;/code&gt;to check. If you need to install it, follow How To Install Git and set it up on your machine before continuing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;GitHub account&lt;/strong&gt; with a new empty repository named multi-env-app. App Platform deploys directly from GitHub, so your code must be hosted there before you can connect it to &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt;. You can sign up for free at &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;github&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;&lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; account&lt;/strong&gt; with access to App Platform. If you are new to &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt;, you can sign up at &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; and follow the App Platform getting started documentation before proceeding.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Familiarity with Next.js and React&lt;/strong&gt;, specifically what components and pages are and how they relate to each other. If you need to build your foundational knowledge first, follow How To Create a Next.js App before starting this tutorial.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaways:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A multi-environment setup separates your application into distinct deployments, typically staging and production, allowing you to test changes safely before they affect real users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; App Platform deploys directly from a GitHub repository, automatically rebuilding and redeploying your app every time you push to a connected branch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Environment variables in Next.js prefixed with &lt;code&gt;NEXT_PUBLIC_&lt;/code&gt; are embedded into the client bundle at build time. They are publicly visible, while variables without the prefix remain server-side only and should be used for secrets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each App Platform deployment maintains its own set of environment variables, meaning your staging and production apps can point to different APIs and configurations while running identical code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A Git branch-based promotion workflow where the staging branch maps to the staging environment and the main branch maps to production gives you a reliable, repeatable process for shipping changes safely.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keeping &lt;code&gt;.env.local&lt;/code&gt; out of version control by adding it to &lt;code&gt;.gitignore&lt;/code&gt; and committing only &lt;code&gt;.env.example&lt;/code&gt; as a reference template is a critical security practice that prevents secrets from being accidentally exposed on GitHub.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Multi-Environment?
&lt;/h2&gt;

&lt;p&gt;A multi-environment setup means running separate, isolated versions of the same application, each with its own configuration, URL, and purpose. &lt;/p&gt;

&lt;p&gt;Rather than maintaining one live deployment that everyone shares, you maintain distinct environments that represent different stages of your development workflow.&lt;/p&gt;

&lt;p&gt;Most teams work with three environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Local is where development happens. It runs on your machine, points to local APIs, and is never visible to anyone else. You can break things freely here without consequence.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Staging is a production-like environment used for testing and review. It runs the same code and infrastructure as production but uses test data and non-critical API endpoints. Think of it as a dress rehearsal before the real show.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Production is the live environment where real users interact. Changes here have real consequences, which is why nothing should reach it without first passing through staging.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What makes this work is that each environment runs the same codebase with different configuration values. There is no separate "staging version" of your code. &lt;/p&gt;

&lt;p&gt;The same application reads its environment variables at build time and behaves accordingly, which is exactly what you will see in action throughout this tutorial.&lt;/p&gt;

&lt;p&gt;The cost of skipping this setup only becomes clear after something breaks in production. A multi-environment architecture does not prevent bugs, but it ensures they are caught early, when the stakes are low, before they reach the people who depend on your product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Simple Next.js App
&lt;/h2&gt;

&lt;p&gt;In this section, we are going to build a simple Next.js App&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Creating the Repository on GitHub
&lt;/h2&gt;

&lt;p&gt;In this step, you will create a GitHub repository to host your project. App Platform deploys directly from GitHub, so your code must be hosted there before you can connect it to &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Navigate to &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;github&lt;/a&gt; and click the "New" button to create a new repository. Fill in the details as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set the Repository name to multi-env-app&lt;/li&gt;
&lt;li&gt;Set the Visibility to Public&lt;/li&gt;
&lt;li&gt;Check the box labelled Add a README file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Checking the Add a README file option initializes the repository with a first commit. This means Git treats the repository as having an existing history, so you can clone it to your local machine immediately without running any additional initialization commands.&lt;/p&gt;

&lt;p&gt;Click Create repository when you are done. You have created your remote repository on GitHub, and it is ready to receive your project files. In the next step, you will clone it to your local machine and open it in your code editor. &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Cloning the Repository and Opening It in VS Code
&lt;/h2&gt;

&lt;p&gt;In this step, you will clone the repository to your local machine and open it in VS Code so you have a working local copy ready for development.&lt;/p&gt;

&lt;p&gt;Run the following command in your terminal to clone the repository, replacing &lt;code&gt;YOUR_USERNAME&lt;/code&gt; with your actual GitHub username:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/YOUR_USERNAME/multi-env-app.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command downloads the repository from GitHub and creates a local copy of it in a folder named multi-env-app on your machine.&lt;/p&gt;

&lt;p&gt;Move into the project directory:&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="nb"&gt;cd &lt;/span&gt;multi-env-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open the folder in VS Code:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;code.&lt;/code&gt; command launches VS Code with the current directory open as the project workspace. If this command is not recognized in your terminal, follow the VS Code Shell Command installation guide to enable it.&lt;/p&gt;

&lt;p&gt;At this point, your project contains only the &lt;code&gt;README.md&lt;/code&gt; file that GitHub created. In the next step, you will scaffold the &lt;code&gt;Next.js&lt;/code&gt; application inside this directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Scaffolding the Next.js Application
&lt;/h2&gt;

&lt;p&gt;In this step, you will scaffold a new Next.js application directly into your existing project directory. This generates all the files and folders you need to start building your app.&lt;/p&gt;

&lt;p&gt;Run the following command to create the Next.js application inside the current directory:&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@latest &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dot (&lt;code&gt;.&lt;/code&gt;) tells the scaffolding tool to use the current directory instead of creating a new nested folder. &lt;/p&gt;

&lt;p&gt;Without it, the tool would create a &lt;code&gt;multi-env-app&lt;/code&gt; folder inside your existing &lt;code&gt;multi-env-app&lt;/code&gt; folder, which would break your repository structure.&lt;/p&gt;

&lt;p&gt;The tool will prompt you with a series of configuration questions. Answer them exactly as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Would you like to use TypeScript?             No
Would you like to use ESLint?                 Yes
Would you like to use Tailwind CSS?           Yes
Would you like your code inside a src/ dir?   No
Would you like to use App Router?             Yes
Would you like to use Turbopack?              No
Would you like to customize the import alias? No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is why each choice matters for this tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;: No — This tutorial uses JavaScript to keep the code accessible to a wider audience. The concepts apply equally to TypeScript projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ESLint&lt;/strong&gt;: Yes — ESLint catches common code errors during development and is a standard part of most production Next.js setups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt;: Yes — You will use Tailwind utility classes to style the environment banner directly in your JSX, without creating any separate CSS files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;App Router&lt;/strong&gt;: Yes — The App Router is the current recommended routing system in Next.js and is built around this tutorial.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;src/ directory, Turbopack, import alias&lt;/strong&gt;: No—These are not needed for this tutorial and would add unnecessary complexity.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the prompts are complete, create-next-app will install all dependencies and automatically generate your project files.&lt;/p&gt;

&lt;p&gt;You now have a fully scaffolded Next.js application in your project directory. In the next step, you will create the environment variable files that allow your app to behave differently depending on where it is deployed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Creating the Environment Variable Files
&lt;/h2&gt;

&lt;p&gt;In this step, you will create environment variable files that allow your app to read different configuration values depending on where it runs. You will also update your &lt;code&gt;.gitignore&lt;/code&gt; file to ensure that secrets are never committed to GitHub.&lt;/p&gt;

&lt;p&gt;Open your editor and create a new file named &lt;code&gt;.env.local&lt;/code&gt; in the root of your project. Add the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;NEXT_PUBLIC_APP_ENV&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;local&lt;/span&gt;
&lt;span class="py"&gt;NEXT_PUBLIC_API_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://localhost:3000/api&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file holds the configuration values for your local development environment. Next.js loads &lt;code&gt;.env.local&lt;/code&gt;automatically when you run the development server, so these values will be available to your app without any additional setup.&lt;/p&gt;

&lt;p&gt;Next, create a second file named &lt;code&gt;.env.example&lt;/code&gt; in the same root location and add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;NEXT_PUBLIC_APP_ENV&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;
&lt;span class="py"&gt;NEXT_PUBLIC_API_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike &lt;code&gt;.env.local&lt;/code&gt;, this file contains the variable names but no values. It acts as a reference template for anyone who clones the repository, showing them exactly which variables they need to configure without exposing any real values.&lt;/p&gt;

&lt;p&gt;Now open the &lt;code&gt;.gitignore&lt;/code&gt;file that Next.js generated automatically and locate the following line:&lt;br&gt;
&lt;code&gt;.env *&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This wildcard pattern tells Git to ignore all files that begin with &lt;code&gt;.env&lt;/code&gt;, which correctly prevents &lt;code&gt;.env.local&lt;/code&gt; from being committed to GitHub. However, it also ignores .env.example, which you do want to commit so other developers can reference it. Add the following line directly below it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.env*
!.env.example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exclamation mark creates an exception to the wildcard rule, telling Git to track &lt;code&gt;.env.example&lt;/code&gt;, even though all other .env files are ignored. With this change in place, your local secrets stay protected while the reference template remains visible in the repository.&lt;/p&gt;

&lt;p&gt;You have set up your environment variable files and secured your &lt;code&gt;.gitignore&lt;/code&gt;. In the next step, you will build the environment banner component that reads these values and displays them visually in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Building the Environment Banner Component
&lt;/h2&gt;

&lt;p&gt;In this step, you will create a React component that reads your environment variables and displays them as a colored banner at the top of the page. This makes it immediately clear which environment you are looking at whenever you open the app in a browser.&lt;/p&gt;

&lt;p&gt;Create a new folder named components in the root of your project. Inside it, create a new file named &lt;code&gt;EnvBanner.js:&lt;/code&gt;&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="nb"&gt;mkdir &lt;/span&gt;components &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;touch &lt;/span&gt;components/EnvBanner.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;components/EnvBanner.js&lt;/code&gt; in your editor and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;jsx&lt;/span&gt;
&lt;span class="c1"&gt;// components/EnvBanner.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;EnvBanner&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEXT_PUBLIC_APP_ENV&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;apiUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEXT_PUBLIC_API_URL&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;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;local&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-gray-800&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LOCAL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;staging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-yellow-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;STAGING&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-green-600&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PRODUCTION&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-gray-500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UNKNOWN&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bg&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; text-white text-sm font-mono px-4 py-2 text-center`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      🌍 Environment: &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="ni"&gt;&amp;amp;nbsp;&lt;/span&gt;|&lt;span class="ni"&gt;&amp;amp;nbsp;&lt;/span&gt; API:&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;code&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bg-black/20 px-1 rounded"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;apiUrl&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;code&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what each part of the component does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;process.env.NEXT_PUBLIC_APP_ENV&lt;/code&gt; and &lt;code&gt;process.env.NEXT_PUBLIC_API_URL&lt;/code&gt; These lines read the two environment variables you defined in &lt;code&gt;.env.local&lt;/code&gt;. Next.js makes any variable prefixed with &lt;code&gt;NEXT_PUBLIC_&lt;/code&gt;available directly in the browser bundle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;styles object&lt;/strong&gt; — This maps each environment name to a Tailwind background color and a display label. local renders in dark gray, staging in yellow, and production in green, making each environment visually distinct at a glance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;current fallback&lt;/strong&gt; — If &lt;code&gt;NEXT_PUBLIC_APP_ENV&lt;/code&gt; is not set or holds an unexpected value, the banner falls back to gray and displays whatever value it finds. This makes misconfigurations immediately visible in the browser rather than failing silently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The returned JSX&lt;/strong&gt; — Renders a full-width banner using the resolved color and label, with the API URL displayed alongside it for quick reference.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You have built the banner component that will visually reflect your environment configuration. In the next step, you will update the homepage to render this component so it appears at the top of every page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Updating the Homepage
&lt;/h2&gt;

&lt;p&gt;In this step, you will update the homepage to render the environment banner and display a config card showing the current environment variable values. This gives you a single page that makes your entire environment configuration visible at a glance.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;app/page.js&lt;/code&gt; in your editor and replace its entire contents with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;jsx&lt;/span&gt;
&lt;span class="c1"&gt;// app/page.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;EnvBanner&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;@/components/EnvBanner&lt;/span&gt;&lt;span class="dl"&gt;"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"min-h-screen bg-gray-50"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;EnvBanner&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"max-w-2xl mx-auto mt-20 px-6 text-center"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-4xl font-bold text-gray-800 mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          Multi-Environment App
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-gray-500 text-lg"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          This app reads its configuration from environment variables.
          The banner above changes depending on where this app is deployed.
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mt-10 bg-white rounded-xl shadow p-6 text-left"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-sm font-semibold text-gray-400 uppercase mb-3"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            Current Config
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"space-y-2 font-mono text-sm"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-gray-400"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;APP_ENV: &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-indigo-600 font-bold"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEXT_PUBLIC_APP_ENV&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;not set&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-gray-400"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;API_URL: &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-indigo-600"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEXT_PUBLIC_API_URL&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;not set&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what each part of the updated homepage does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;import EnvBanner from&lt;code&gt;@/components/EnvBanner&lt;/code&gt;&lt;/strong&gt; — This imports the banner component you built in the previous step. The &lt;code&gt;@/&lt;/code&gt;prefix is an alias for the project root, configured automatically by create-next-app. It lets you import files without writing long relative paths like &lt;code&gt;../../components/EnvBanner&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;EnvBanner&lt;/strong&gt; — Renders the colored environment banner at the very top of the page, before any other content.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The config card&lt;/strong&gt; — Displays the current values of &lt;code&gt;NEXT_PUBLIC_APP_ENV&lt;/code&gt; and &lt;code&gt;NEXT_PUBLIC_API_URL&lt;/code&gt; directly on the page. If either variable is not set, it falls back to displaying "not set," so misconfigurations are immediately visible.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You have updated the homepage to display both the environment banner and the current configuration values. In the next step, you will run the app locally to confirm everything is working before deploying to App Platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Running the App Locally
&lt;/h2&gt;

&lt;p&gt;In this step, start the development server and verify that your app is reading environment variables correctly before deploying it to App Platform.&lt;/p&gt;

&lt;p&gt;Run the following command to start the development server:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This command compiles your Next.js application and starts a local server that watches for file changes and reloads automatically.&lt;/p&gt;

&lt;p&gt;Open your browser and navigate to &lt;code&gt;http://localhost:3000&lt;/code&gt;. You should see the following output across the top of the page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
🌍 Environment: LOCAL  |  API: http://localhost:3000/api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dark gray banner confirms that your app is reading &lt;code&gt;NEXT_PUBLIC_APP_ENV&lt;/code&gt; and &lt;code&gt;NEXT_PUBLIC_API_URL&lt;/code&gt; directly from your &lt;code&gt;.env.local file&lt;/code&gt;. Below the banner, the config card will display the same values, showing that no values are hardcoded into the UI; everything comes from configuration.&lt;/p&gt;

&lt;p&gt;This is an important distinction. When you deploy this same codebase to App Platform in the next steps and set &lt;code&gt;NEXT_PUBLIC_APP_ENV=staging&lt;/code&gt;, the banner will turn yellow and update automatically without a single line of code changing. &lt;/p&gt;

&lt;p&gt;The code remains identical across all environments; only the configuration changes.&lt;/p&gt;

&lt;p&gt;You have confirmed that your app is environment-aware and working correctly on your local machine. &lt;/p&gt;

&lt;p&gt;In the next step, you will commit your project to GitHub so that App Platform can access it for deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8: Committing and Pushing to GitHub
&lt;/h2&gt;

&lt;p&gt;In this step, you will commit your project files to Git and push them to GitHub so that App Platform can access your code for deployment.&lt;/p&gt;

&lt;p&gt;Before staging any files, confirm that .env.local is not going to be committed by running:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;You should see output similar to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
Untracked files:
  (use "git add &amp;lt;file&amp;gt;..." to include in what will be committed)
        .env.example
        components/
        app/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;.env.example&lt;/code&gt; should appear as an untracked file, but .env.local should not appear anywhere in the output. If &lt;code&gt;.env.local&lt;/code&gt; is visible, stop and review your .gitignore before continuing. &lt;/p&gt;

&lt;p&gt;Committing it would expose your local configuration to anyone who can view the repository on GitHub.&lt;/p&gt;

&lt;p&gt;Once you have confirmed everything looks correct, stage all the files:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Commit the staged files with a descriptive message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"initial Next.js app with env banner."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then push the commit to GitHub:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This pushes your code to the main branch of your remote repository on GitHub, which is the branch App Platform will connect to for the production environment.&lt;/p&gt;

&lt;p&gt;After the push completes, visit your repository on GitHub and confirm that &lt;code&gt;components/EnvBanner.js&lt;/code&gt;, &lt;code&gt;app/page.js&lt;/code&gt;, and &lt;code&gt;.env.example&lt;/code&gt; are all visible in the file list. The &lt;code&gt;.env.local&lt;/code&gt;file should not appear anywhere in the repository.&lt;/p&gt;

&lt;p&gt;You have pushed your project to GitHub and confirmed that your secrets are protected. &lt;/p&gt;

&lt;p&gt;In the next step, you will connect your repository to &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; App Platform and deploy your staging environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Staging Environment
&lt;/h2&gt;

&lt;p&gt;Throughout this tutorial, you will use a simple two-branch strategy that maps directly to your two environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The main branch represents production. Code on this branch is live, and real users can see it. Nothing should reach main without first being tested on staging.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The staging branch represents the staging environment. This is where all new work lands first. It is a safe, production-like environment where you can verify that changes behave correctly before they affect real users.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, the workflow looks like this: you build and test a new feature on the staging branch, confirm it works on the staging URL, and then merge it into main to promote it to production. &lt;/p&gt;

&lt;p&gt;App Platform watches both branches independently and redeploys the appropriate environment whenever either one receives a push.&lt;/p&gt;

&lt;p&gt;To create the staging branch, run the following in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; staging
git push origin staging
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You now have two branches on GitHub: main and staging, and your repository is ready to be connected to App Platform. &lt;/p&gt;

&lt;p&gt;In the next step, you will create two separate App Platform apps, one pointing at each branch, and configure them with their own environment variables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Your First App on App Platform
&lt;/h2&gt;

&lt;p&gt;In this section, we will cover how to deploy the Next.js application you just built to &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; App Platform with separate staging and production environments. &lt;/p&gt;

&lt;p&gt;You will connect to a GitHub repository, configure environment variables for each environment, and verify that each deployment reads the correct values.&lt;/p&gt;

&lt;p&gt;By the end, you will have a live staging URL displaying the correct environment banner and a clear process you can repeat for production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Accessing App Platform
&lt;/h2&gt;

&lt;p&gt;In this step, you will log in to your &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; account and navigate to App Platform, the service that hosts, builds, and deploys your Next.js application directly from GitHub.&lt;/p&gt;

&lt;p&gt;Open your browser and go to &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Enter your email and password, then click Log In. Once you are on the control panel dashboard, click App Platform in the left-hand sidebar. &lt;/p&gt;

&lt;p&gt;This opens the App Platform section, which lists all your deployed apps. In the top-right corner of the Apps page, click the blue Create App button.&lt;/p&gt;

&lt;p&gt;After clicking Create App, you are taken to a multi-step wizard. The first screen, titled Create App, asks you to choose a source for your code. &lt;/p&gt;

&lt;p&gt;In the next step, you will connect your GitHub repository, so App Platform knows where to pull your code from.&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%2Fdmrpprlmwdpcyjh79j4q.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%2Fdmrpprlmwdpcyjh79j4q.png" alt="DigitalOcean App Platform dashboard showing multiple deployment environments and how to create an app" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Connecting Your GitHub Repository
&lt;/h2&gt;

&lt;p&gt;In this step, you will link&lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt; DigitalOcean&lt;/a&gt; to your GitHub account and grant it access to the multi-env-app repository. &lt;/p&gt;

&lt;p&gt;This connection is what allows App Platform to pull your code and trigger automatic deployments whenever you push a new commit.&lt;/p&gt;

&lt;p&gt;The Create App wizard opens on the source selection screen. Under Git Provider, click the GitHub tile. A Connect to GitHub button will appear; click it.&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%2Fuws0mlig0cc5hbakzbsx.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%2Fuws0mlig0cc5hbakzbsx.png" alt="Connect and Select Repository on the App Platform" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A GitHub OAuth pop-up window will open. Do not close it. Inside the pop-up, click Authorize &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; to grant &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; read access to your GitHub repositories.&lt;/p&gt;

&lt;p&gt;GitHub will then ask you to choose which repositories to share. Select only the repositories to limit access to just the repository this tutorial needs. &lt;/p&gt;

&lt;p&gt;Use the search box to find multi-env-app, select it, then click Install &amp;amp; Authorize.&lt;/p&gt;

&lt;p&gt;The pop-up will close automatically, and you will be returned to the &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; dashboard with your GitHub account now connected.&lt;/p&gt;

&lt;p&gt;In the next step, you will select the branch and configure the repository source settings to specify which branch to deploy from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure the repository source
&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%2F2tuja5eyzww2h6kl75mh.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%2F2tuja5eyzww2h6kl75mh.png" alt="Configure the repository source" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With GitHub connected, you will now configure the repository source settings. Under Repository, open the dropdown and select multi-env-app. Under Branch, select staging. &lt;/p&gt;

&lt;p&gt;You are setting up the staging environment first, so all deployments from this app will track the staging branch.&lt;/p&gt;

&lt;p&gt;Leave Source Directory set to &lt;code&gt;/&lt;/code&gt; since your Next.js project lives in the root of the repository. &lt;/p&gt;

&lt;p&gt;Check the Autodeploy checkbox to have App Platform rebuild and redeploy automatically whenever you push a commit to the staging branch. &lt;/p&gt;

&lt;p&gt;This is what makes your deployment workflow hands-free once the initial setup is complete.&lt;/p&gt;

&lt;p&gt;Click Next to continue to the Resources screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Configure Your App Resources
&lt;/h2&gt;

&lt;p&gt;In this step, you will review the auto-detected configuration for your Next.js application and select a pricing plan before deploying.&lt;/p&gt;

&lt;p&gt;When App Platform scans your repository, it identifies the project type and suggests a default build configuration. You will see one detected component with the following defaults:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Name:&lt;/strong&gt; multi-env-app (or web)&lt;br&gt;
&lt;strong&gt;Type:&lt;/strong&gt; Web Service&lt;br&gt;
&lt;strong&gt;Build Command:&lt;/strong&gt; &lt;code&gt;npm run build&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Run Command:&lt;/strong&gt; &lt;code&gt;npm start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If either command is missing, click Edit on the component. Enter &lt;code&gt;npm run build&lt;/code&gt; in the Build Command field, and &lt;code&gt;npm start&lt;/code&gt; in the Run Command field, then click Save. &lt;/p&gt;

&lt;p&gt;These commands tell App Platform how to compile your Next.js project and start the production server.&lt;/p&gt;

&lt;p&gt;Next, you will select a pricing plan for your web service. Click Edit Plan on the right side of the detected Web Service component. &lt;/p&gt;

&lt;p&gt;On the plan selection screen, click Basic to select the Basic plan, which costs $5 per month. &lt;/p&gt;

&lt;p&gt;Under Instance Size, select the smallest available option: 512 MB RAM / 1 vCPU is sufficient for testing purposes. Click Back to return to the Resources screen.&lt;/p&gt;

&lt;p&gt;Once you have confirmed your resource configuration, click Next to continue.You have configured your app's build settings and selected a pricing plan. &lt;/p&gt;

&lt;p&gt;In the next step, you will set up your environment variables so that App Platform can pass the correct configuration values to your application at build time and runtime.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Setting Environment Variables
&lt;/h2&gt;

&lt;p&gt;In this step, you will configure the environment variables that define your application's staging environment. Because Next.js reads these values at build time and embeds them directly in the browser bundle, setting them correctly here is the most critical part of this setup.&lt;/p&gt;

&lt;p&gt;You should now be on the Environment Variables screen. Click Edit next to your web service component name to begin adding variables.&lt;/p&gt;

&lt;p&gt;Start by adding the first variable. Click Add Variable, and a row with two input fields and a checkbox will appear. In the Key field, enter the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NEXT_PUBLIC_APP_ENV&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the Value field, enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;staging

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Leave the Encrypt checkbox unchecked. Because this variable uses the &lt;code&gt;NEXT_PUBLIC_&lt;/code&gt; prefix, Next.js intentionally exposes it to the browser, so encryption is not necessary here.&lt;/p&gt;

&lt;p&gt;Next, click Add Variable again to create a second row. In the Key field, enter the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NEXT_PUBLIC_API_URL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the Value field, enter your staging API endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://staging-api.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Leave Encrypt unchecked for this variable as well, then click Save to confirm both variables.You have configured the environment variables that distinguish your staging deployment from production. &lt;/p&gt;

&lt;p&gt;In the next step, you will review your settings and deploy the application to App Platform.&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%2Fmlkme2kb8q0lc7egs33n.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%2Fmlkme2kb8q0lc7egs33n.png" alt="Setting Environment Variables" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Never encrypt public variables. Any key prefixed with &lt;code&gt;NEXT_PUBLIC_&lt;/code&gt; is embedded in the compiled JavaScript and sent to every browser that loads the page. &lt;/p&gt;

&lt;p&gt;Checking "Encrypt" on these variables will cause the build to fail because Next.js cannot access encrypted values at build time.&lt;/p&gt;

&lt;p&gt;Reserve encryption only for server-side secrets such as database passwords.&lt;/p&gt;

&lt;p&gt;After saving, you should see a confirmation summary showing both variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;NEXT_PUBLIC_APP_ENV&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt;  &lt;span class="s"&gt;staging&lt;/span&gt;
&lt;span class="py"&gt;NEXT_PUBLIC_API_URL&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt;  &lt;span class="s"&gt;https://staging-api.example.com&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click "Next" to continue&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Name Your App and Choose a Region
&lt;/h2&gt;

&lt;p&gt;In this step, you will give your app an identifiable name and select the data center that will host it. &lt;/p&gt;

&lt;p&gt;You should now be on the Info screen. Click inside the App Name field, clear the existing value, and enter the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;multi-env-staging
&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%2Fuploads%2Farticles%2Fhyycs94kffao8dnsozwc.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%2Fhyycs94kffao8dnsozwc.png" alt="Name your project Region" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Naming your app this way makes it immediately clear which environment you are looking at in the dashboard, particularly once you have both staging and production apps listed side by side.&lt;/p&gt;

&lt;p&gt;Next, open the Region dropdown and select the data center closest to your users. For example, choose New York (NYC) on the US East Coast, Amsterdam (AMS) in Europe, or Singapore (SGP) in the Asia-Pacific. Placing your app geographically close to your users reduces latency and improves response times.&lt;/p&gt;

&lt;p&gt;Once you have set the name and region, click Next to continue. You have named your staging app and selected a hosting region. In the next step, you will review your complete configuration before deploying the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Reviewing and Creating Your App
&lt;/h2&gt;

&lt;p&gt;In this step, you will review your complete configuration and deploy your staging application to App Platform.&lt;/p&gt;

&lt;p&gt;The final screen is a summary of all the configurations you have made. Read through it carefully and confirm that each of the following values is correct before proceeding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source&lt;/strong&gt;: multi-env-app repository, staging branch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Autodeploy&lt;/strong&gt;: Enabled&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type&lt;/strong&gt;: Web Service (Next.js)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan&lt;/strong&gt;: Basic, $5/month&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment Variables&lt;/strong&gt;: &lt;code&gt;NEXT_PUBLIC_APP_ENV=staging&lt;/code&gt; and &lt;code&gt;NEXT_PUBLIC_API_URL&lt;/code&gt; set&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App Name&lt;/strong&gt;: &lt;code&gt;multi-env-staging&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If anything looks incorrect, click Back to return to the relevant screen and correct it before proceeding. Once you are satisfied that all values are correct, click Create Resources to deploy your application.&lt;/p&gt;

&lt;p&gt;You have reviewed your configuration and triggered your first deployment. In the next step, you will monitor the build process and verify that your staging environment is running correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Monitoring the Deployment
&lt;/h2&gt;

&lt;p&gt;In this step, you will watch the build log to confirm that your application deploys successfully through each stage of the pipeline.&lt;/p&gt;

&lt;p&gt;After clicking Create Resources, App Platform immediately begins building and deploying your app. A live log will appear on screen as the process runs. You will see the following stages complete in order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cloning repository: App Platform pulls the code from the staging branch of the multi-env-app repository on GitHub.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Installing dependencies: App Platform runs npm install to install all packages listed in package.json.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building: App Platform runs npm run build, which compiles the Next.js application and embeds your environment variables into the output bundle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Uploading artifact: The compiled build is packaged and stored in preparation for deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deploying: The container starts, and your app begins serving traffic.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any stage fails, App Platform will log the error. Read the error message carefully; most build failures at this stage are caused by a missing environment variable or an incorrect build command. &lt;/p&gt;

&lt;p&gt;If that happens, click Settings to review your configuration, make the necessary correction, and then trigger a new deploy by clicking Actions &amp;gt; Force Rebuild and Deploy.&lt;/p&gt;

&lt;p&gt;Once all five stages are completed successfully, App Platform will display a green Live badge next to your app name. You have successfully deployed your staging environment to App Platform.&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%2F8gw8t4wm35omo2r64y1b.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%2F8gw8t4wm35omo2r64y1b.png" alt="Building the project" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A successful deployment produces output similar to the following at the end of the build log:&lt;/p&gt;

&lt;p&gt;The initial deployment typically takes 3 to 5 minutes. The app's status indicator changes from "Building" (yellow) to "Deployed" (green) when it is ready.&lt;/p&gt;

&lt;p&gt;If the deployment fails, click on the failed deployment to expand the full build log. Scroll to the first line marked ERROR to find the cause. Common causes are a missing dependency in package.json, a TypeScript type error that fails the build, or an incorrectly named environment variable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8: Test Your Staging Deployment
&lt;/h2&gt;

&lt;p&gt;In this step, you will open your deployed application in a browser and confirm that it is reading the correct environment variables.&lt;/p&gt;

&lt;p&gt;Navigate to the Deployments tab in App Platform and copy your live URL, which will look like the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://multi-env-staging-xxxxx.ondigitalocean.app&lt;/code&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%2Fuploads%2Farticles%2Fv72clq0bk49q6ku9jqck.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%2Fv72clq0bk49q6ku9jqck.png" alt="Live Site Staging " width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Paste the URL into your browser and press Enter. Once the page loads, look at the top of the screen and confirm the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A yellow banner reading Environment: STAGING is visible at the top of the page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The API URL displayed on the page matches &lt;a href="https://staging-api.example.com" rel="noopener noreferrer"&gt;https://staging-api.example.com&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the banner is missing or shows a different environment, your &lt;code&gt;NEXT_PUBLIC_APP_ENV&lt;/code&gt;variable was not set correctly. If the API URL is wrong or absent, check the value you entered for &lt;code&gt;NEXT_PUBLIC_API_URL&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In either case, return to Settings &amp;gt; App-Level Environment Variables, correct the value, and click Actions &amp;gt; Force Rebuild and Deploy to redeploy with the updated configuration.&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%2Fh3acea22dbt8skqikfdg.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%2Fh3acea22dbt8skqikfdg.png" alt="Yellow Banner Staging" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deployment confirmed. If you see the yellow STAGING banner with the correct API URL, your staging environment is live, and your environment variables are being read correctly by the Next.js application. &lt;/p&gt;

&lt;p&gt;In the next step, you will set up your production app using the same process with a separate set of values.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Production Environment
&lt;/h2&gt;

&lt;p&gt;With staging live and verified, you are ready to deploy production. The setup follows the same wizard you used for staging. This section only covers what is different.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create a New App and Connect the Main Branch
&lt;/h2&gt;

&lt;p&gt;From the App Platform dashboard, click "Create App". &lt;/p&gt;

&lt;p&gt;Since you already authorized &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; to access your GitHub account during the staging setup, you will not need to go through the OAuth flow again. &lt;/p&gt;

&lt;p&gt;Under "Service Provider", select GitHub and configure the repository source as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Repository: multi-env-app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Branch: main&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Autodeploy: Enabled&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Leave "Source Directory" set to / and click "Next".&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%2F26bp5ba3onxhdboxdv9w.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%2F26bp5ba3onxhdboxdv9w.png" alt="Repository" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Set Production Environment Variables
&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%2Fhqvikiexulqpd58smsoy.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%2Fhqvikiexulqpd58smsoy.png" alt=" " width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the "Environment Variables" screen, add both variables exactly as shown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;NEXT_PUBLIC_APP_ENV&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt;  &lt;span class="s"&gt;production&lt;/span&gt;
&lt;span class="py"&gt;NEXT_PUBLIC_API_URL&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt;  &lt;span class="s"&gt;https://api.example.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike the staging setup,&lt;code&gt;NEXT_PUBLIC_API_URL&lt;/code&gt; here points to your real production API endpoint. Leave "Encrypt" unchecked for both variables for the same reasons covered in the staging setup. Click "Save", then "Next".&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Name Your App and Review
&lt;/h2&gt;

&lt;p&gt;On the "Info" screen, name the app "multi-env-production" and select the same region you used for staging to keep latency consistent across environments.&lt;/p&gt;

&lt;p&gt;On the final review screen, confirm the following before clicking "Create Resources":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Source: multi-env-app repository, main branch&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Autodeploy: Enabled&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Environment variables: &lt;code&gt;NEXT_PUBLIC_APP_ENV=production&lt;/code&gt; and &lt;code&gt;NEXT_PUBLIC_API_URL&lt;/code&gt; set&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;App name: multi-env-production&lt;/p&gt;&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%2Fk6szcrpee37ydtt7bfs8.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%2Fk6szcrpee37ydtt7bfs8.png" alt="Name Production" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Verify the Production Deployment
&lt;/h2&gt;

&lt;p&gt;Once the status shows "Deployed", copy the live URL from the Deployments tab and open it in your browser. Confirm the following:&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%2Fx5vphle6xjbfa53eph4l.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%2Fx5vphle6xjbfa53eph4l.png" alt="Enivironment Building" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A green banner reading "Environment: PRODUCTION" is visible at the top of the page&lt;/li&gt;
&lt;li&gt;The API URL displayed matches &lt;a href="https://api.example.com" rel="noopener noreferrer"&gt;https://api.example.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you see the green banner with the correct API URL, your production environment is live. You now have two fully independent deployments running identical code, each reading its own configuration.&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%2Fnu7ab3noh4qrrn02ao6m.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%2Fnu7ab3noh4qrrn02ao6m.png" alt="productionready" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Can I use this same multi-environment setup with an existing Next.js project, or does it only work with a freshly scaffolded app?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes, you can apply this setup to any existing Next.js project. The core requirements are that your project has a package.json with build and start scripts, and that your environment variables follow the &lt;code&gt;NEXT_PUBLIC_&lt;/code&gt; prefix convention. &lt;/p&gt;

&lt;p&gt;Simply create your &lt;code&gt;.env.local&lt;/code&gt;and &lt;code&gt;.env.example&lt;/code&gt; files, update your &lt;code&gt;.gitignore&lt;/code&gt;, and connect your existing repository to App Platform following the same steps covered in this tutorial.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What happens if I accidentally commit .env.local to GitHub?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remove it immediately. Run &lt;code&gt;git rm --cached .env.local&lt;/code&gt; to stop tracking the file without deleting it locally, commit that change, and push it to GitHub. &lt;/p&gt;

&lt;p&gt;Then, rotate any exposed values treat them as compromised regardless of whether your repository is public or private. After that, verify your &lt;code&gt;.gitignore&lt;/code&gt; contains the &lt;code&gt;.env*&lt;/code&gt; pattern with the &lt;code&gt;!.env.example&lt;/code&gt; exception before continuing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Will the autodeploy trigger for both staging and production every time I push to any branch?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No. Each App Platform app watches only the branch you connected it to. Pushing to staging triggers a rebuild of your staging app only, and pushing to main triggers a rebuild of production only. The two deployments are fully independent and do not affect each other.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Can I add more than two environments, such as a QA or preview environment?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes. You can create as many App Platform apps as you need, each connected to a different branch with its own environment variables. Simply create a new branch in your repository, spin up a new App Platform app pointed at that branch, and configure the appropriate variable values. The same workflow applies regardless of how many environments you add.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Does this setup work with frameworks other than Next.js?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes. App Platform supports a wide range of frameworks, including Remix, Astro, SvelteKit, and plain Node.js applications. &lt;/p&gt;

&lt;p&gt;The environment variable strategy described in this tutorial, using platform-level variables to configure deployments without changing code, applies to any framework that reads from process.env at build or runtime. &lt;/p&gt;

&lt;p&gt;Check the App Platform documentation for framework-specific build and run command requirements.&lt;/p&gt;

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

&lt;p&gt;You have built and deployed a multi-environment Next.js application on &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean &lt;/a&gt;App Platform. You scaffolded a Next.js project, configured environment variables to control application behavior, and built an environment banner that makes your active configuration immediately visible in the browser. &lt;/p&gt;

&lt;p&gt;You then connected your GitHub repository to App Platform and deployed two fully independent environments, &lt;code&gt;staging&lt;/code&gt; tracking the &lt;code&gt;staging branch&lt;/code&gt; and production tracking main, each reading its own set of environment variables from the same codebase.&lt;/p&gt;

&lt;p&gt;You now have a repeatable promotion workflow: build and test on the staging branch, verify the changes on your staging URL, and &lt;code&gt;merge&lt;/code&gt; into main to ship to production. Autodeploy handles the rest automatically on every push.&lt;/p&gt;

&lt;p&gt;From here, you can extend this setup in several directions. As your application grows, you can add additional &lt;code&gt;NEXT_PUBLIC_&lt;/code&gt;variables for feature flags, analytics keys, or third-party service endpoints without touching your application code. &lt;/p&gt;

&lt;p&gt;For sensitive server-side values like database passwords or private API keys, revisit your App Platform environment variable settings and use the Encrypt option. These values are never embedded in the browser bundle and are safe to protect this way.&lt;/p&gt;

&lt;p&gt;If you want to go further, &lt;a href="https://docs.digitalocean.com/products/app-platform/" rel="noopener noreferrer"&gt;DigitalOcean's App Platform&lt;/a&gt; documentation covers custom domains, alerting, and autoscaling for when your application is ready to grow beyond a basic plan. &lt;/p&gt;

&lt;p&gt;You can also explore Next.js's &lt;a href="https://nextjs.org/docs/app/building-your-application/configuring/environment-variables" rel="noopener noreferrer"&gt;environment variable documentation&lt;/a&gt; for a deeper understanding of how build-time and runtime variables differ and when to use each.&lt;/p&gt;

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

&lt;p&gt;For more information about App Platform and web app deployment, you can check out the following tutorials: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/conceptual-articles/best-practices-app-platform-multi-environment" rel="noopener noreferrer"&gt;Multi-Environment Setup on App Platform: Development, Staging, Production Best Practices&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/app-lifecycle-development-app-platform-claude" rel="noopener noreferrer"&gt;App Lifecycle Development on DigitalOcean App Platform using Claude Code&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/conceptual-articles/digitalocean-app-platform-vs-doks-vs-droplets" rel="noopener noreferrer"&gt;DigitalOcean App Platform vs DOKS vs Droplets: The Ultimate Comparison for Dev Teams&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article is part of the &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; Ripple Writers program. I received compensation and platform credits for writing this content, but all technical assessments, code, and opinions are my own based on hands-on testing.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>digitalocean</category>
      <category>deployment</category>
    </item>
  </channel>
</rss>
