From a1fb25efd07fcd290a157835c330766b3fef7997 Mon Sep 17 00:00:00 2001
From: Remon Oldenbeuving
Date: Wed, 17 Jun 2026 17:32:41 +0200
Subject: [PATCH 1/3] feat(web): distinguish staging environment
---
ENVIRONMENT.md | 1 +
apps/web/public/kilo-v1-STAGING.svg | 13 ++++++
apps/web/src/app/layout.tsx | 40 ++++++++++++-------
.../shared/StagingEnvironmentBanner.tsx | 12 ++++++
4 files changed, 51 insertions(+), 15 deletions(-)
create mode 100644 apps/web/public/kilo-v1-STAGING.svg
create mode 100644 apps/web/src/components/shared/StagingEnvironmentBanner.tsx
diff --git a/ENVIRONMENT.md b/ENVIRONMENT.md
index d38935b390..a317f0ca71 100644
--- a/ENVIRONMENT.md
+++ b/ENVIRONMENT.md
@@ -46,6 +46,7 @@ This document lists all environment variables used in the Kilo Code cloud monore
### Vercel & Build Info
- `VERCEL_ENV` - Vercel environment (`development`, `preview`, `production`); used in `apps/web/next.config.mjs`, `apps/web/src/lib/constants.ts`, and `apps/web/.env.test`. [SERVER]
+- `VERCEL_TARGET_ENV` - Vercel system or custom deployment environment (`development`, `preview`, `production`, `staging`, etc.); used in `apps/web/src/app/layout.tsx` to identify staging UI. [SERVER]
- `VERCEL_URL` - Auto-injected by Vercel; current deployment URL. Used in `apps/web/src/lib/buildInfo.ts`. [SERVER]
- `VERCEL_GIT_COMMIT_SHA` - Auto-injected by Vercel; Git commit SHA of the current deployment. Used in `apps/web/src/lib/buildInfo.ts`. [SERVER]
- `NEXT_PUBLIC_VERCEL_URL` - Client-exposed Vercel deployment URL from build info. [PUBLIC]
diff --git a/apps/web/public/kilo-v1-STAGING.svg b/apps/web/public/kilo-v1-STAGING.svg
new file mode 100644
index 0000000000..6420fc7815
--- /dev/null
+++ b/apps/web/public/kilo-v1-STAGING.svg
@@ -0,0 +1,13 @@
+
+
diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx
index 2943ba3092..48416235bf 100644
--- a/apps/web/src/app/layout.tsx
+++ b/apps/web/src/app/layout.tsx
@@ -6,6 +6,7 @@ import { PostHogProvider } from '../components/PostHogProvider';
import { Providers } from '../components/Providers';
import { DataLayerProvider } from '../components/DataLayerProvider';
import { ImpactIdentify } from '@/components/ImpactIdentify';
+import { StagingEnvironmentBanner } from '@/components/shared/StagingEnvironmentBanner';
import { APP_URL } from '@/lib/constants';
const inter = Inter({
@@ -26,6 +27,9 @@ const jetbrainsMono = JetBrains_Mono({
variable: '--font-jetbrains',
});
+const isStagingEnvironment = process.env.VERCEL_TARGET_ENV === 'staging';
+const stagingFavicon = '/kilo-v1-STAGING.svg';
+
export const metadata: Metadata = {
title: 'Kilo Code - Open source AI agent VS Code extension',
description:
@@ -47,8 +51,9 @@ export const metadata: Metadata = {
'Write code more efficiently by generating code, automating tasks, and providing suggestions',
},
icons: {
- icon:
- process.env.NODE_ENV !== 'production'
+ icon: isStagingEnvironment
+ ? [{ url: stagingFavicon, type: 'image/svg+xml' }]
+ : process.env.NODE_ENV !== 'production'
? [{ url: '/kilo-v1-DEV.svg', type: 'image/svg+xml' }]
: [
{ url: '/favicon.ico', sizes: '48x48', type: 'image/x-icon' },
@@ -59,24 +64,28 @@ export const metadata: Metadata = {
sizes: '180x180',
type: 'image/png',
},
- shortcut: { url: '/favicon.ico' },
+ shortcut: { url: isStagingEnvironment ? stagingFavicon : '/favicon.ico' },
other: [
{
rel: 'manifest',
url: '/site.webmanifest',
},
- {
- rel: 'icon',
- type: 'image/png',
- sizes: '192x192',
- url: '/favicon/android-chrome-192x192.png',
- },
- {
- rel: 'icon',
- type: 'image/png',
- sizes: '512x512',
- url: '/favicon/android-chrome-512x512.png',
- },
+ ...(isStagingEnvironment
+ ? []
+ : [
+ {
+ rel: 'icon',
+ type: 'image/png',
+ sizes: '192x192',
+ url: '/favicon/android-chrome-192x192.png',
+ },
+ {
+ rel: 'icon',
+ type: 'image/png',
+ sizes: '512x512',
+ url: '/favicon/android-chrome-512x512.png',
+ },
+ ]),
],
},
other: {
@@ -107,6 +116,7 @@ export default function RootLayout({
>
+ {isStagingEnvironment ? : null}
diff --git a/apps/web/src/components/shared/StagingEnvironmentBanner.tsx b/apps/web/src/components/shared/StagingEnvironmentBanner.tsx
new file mode 100644
index 0000000000..5010d41ec1
--- /dev/null
+++ b/apps/web/src/components/shared/StagingEnvironmentBanner.tsx
@@ -0,0 +1,12 @@
+import { FlaskConical } from 'lucide-react';
+
+export function StagingEnvironmentBanner() {
+ return (
+
+ );
+}
From 44fdde31b7fe0d97a3be973bf97c6788be4ee8fc Mon Sep 17 00:00:00 2001
From: "kiloconnect[bot]" <240665456+kiloconnect[bot]@users.noreply.github.com>
Date: Wed, 17 Jun 2026 15:43:31 +0000
Subject: [PATCH 2/3] feat(staging): add dismiss button to staging environment
banner
---
.../components/shared/StagingEnvironmentBanner.tsx | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/apps/web/src/components/shared/StagingEnvironmentBanner.tsx b/apps/web/src/components/shared/StagingEnvironmentBanner.tsx
index 5010d41ec1..8adfea7a23 100644
--- a/apps/web/src/components/shared/StagingEnvironmentBanner.tsx
+++ b/apps/web/src/components/shared/StagingEnvironmentBanner.tsx
@@ -1,12 +1,25 @@
+import { useState } from 'react';
import { FlaskConical } from 'lucide-react';
export function StagingEnvironmentBanner() {
+ const [dismissed, setDismissed] = useState(false);
+
+ if (dismissed) return null;
+
return (
);
}
From dbd89eb2e2d170fb461aaa57ece53381f68ea452 Mon Sep 17 00:00:00 2001
From: "kiloconnect[bot]" <240665456+kiloconnect[bot]@users.noreply.github.com>
Date: Wed, 17 Jun 2026 15:56:12 +0000
Subject: [PATCH 3/3] fix(web): add 'use client' directive to
StagingEnvironmentBanner
---
apps/web/src/components/shared/StagingEnvironmentBanner.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/apps/web/src/components/shared/StagingEnvironmentBanner.tsx b/apps/web/src/components/shared/StagingEnvironmentBanner.tsx
index 8adfea7a23..13134c7261 100644
--- a/apps/web/src/components/shared/StagingEnvironmentBanner.tsx
+++ b/apps/web/src/components/shared/StagingEnvironmentBanner.tsx
@@ -1,3 +1,5 @@
+'use client';
+
import { useState } from 'react';
import { FlaskConical } from 'lucide-react';