Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 53 additions & 49 deletions components/dashboard/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,42 +25,11 @@ import "./index.css";
import { PaymentContextProvider } from "./payment-context";
import { ThemeContextProvider } from "./theme-context";
import { UserContextProvider } from "./user-context";
import { getURLHash, isGitpodIo, isWebsiteSlug } from "./utils";
import { getExperimentsClient } from "./experiments/client";
import { getURLHash, isWebsiteSlug } from "./utils";
// Import the minimal login HTML template at build time
import minimalLoginHtml from "./minimal-login.html";

const MINIMAL_MODE_STORAGE_KEY = "minimal_gitpod_io_mode";
const MINIMAL_MODE_FLAG_NAME = "minimal_gitpod_io_mode";

/**
* Check if we should use minimal gitpod.io mode.
* Priority:
* 1. localStorage override (for testing)
* 2. ConfigCat feature flag
*/
async function shouldUseMinimalMode(): Promise<boolean> {
// Check localStorage override first (sync, for testing)
try {
const localOverride = localStorage.getItem(MINIMAL_MODE_STORAGE_KEY);
if (localOverride === "true") return true;
if (localOverride === "false") return false;
} catch {
// localStorage might not be available
}

// Check ConfigCat feature flag
try {
const client = getExperimentsClient();
const value = await client.getValueAsync(MINIMAL_MODE_FLAG_NAME, false, {
gitpodHost: window.location.host,
});
return value === true;
} catch (error) {
console.error("Failed to check minimal mode flag:", error);
return false; // Fail safe: use full app
}
}
const MINIMAL_MODE_OVERRIDE_KEY = "minimal_gitpod_io_mode";

/**
* Check if the pathname is a known app route that should show the minimal login page
Expand Down Expand Up @@ -159,15 +128,29 @@ function handleMinimalGitpodIoMode(): void {
window.location.href = `https://www.gitpod.io${pathname}${search}`;
}

/**
* Extract body content from a full HTML document string.
* This allows keeping the complete HTML structure in the source file for easier editing.
*/
function extractBodyContent(html: string): string {
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");
return doc.body.innerHTML;
}

/**
* Render a minimal static login page without React.
* Loads the HTML from an external file for easier review and maintenance.
* Uses innerHTML instead of document.write() to avoid deprecation issues.
*/
function renderMinimalLoginPage(): void {
// Replace the entire document with the minimal login page
document.open();
document.write(minimalLoginHtml);
document.close();
const bodyContent = extractBodyContent(minimalLoginHtml);
const root = document.getElementById("root");
if (root) {
root.innerHTML = bodyContent;
} else {
// Fallback if root doesn't exist
document.body.innerHTML = bodyContent;
}
}

/**
Expand Down Expand Up @@ -221,23 +204,44 @@ function bootFullApp(): void {
}

/**
* Main boot function
* Check if this is exactlly gitpod.io
*/
const bootApp = async () => {
// Minimal gitpod.io mode - only on exact "gitpod.io" domain
if (isGitpodIo()) {
const minimalMode = await shouldUseMinimalMode();
function isExactGitpodIo(): boolean {
return window.location.hostname === "gitpod.io";
}

if (minimalMode) {
handleMinimalGitpodIoMode();
/**
* Main boot function
*
* Minimal mode is enabled when:
* - localStorage override is "true" (for testing in preview environments)
* - Host is exactly "gitpod.io" AND path is not a website slug
*/
const bootApp = () => {
let minimalMode = false;

// Handle website slugs on gitpod.io - redirect to www.gitpod.io
if (isExactGitpodIo()) {
const pathname = window.location.pathname;
if (isWebsiteSlug(pathname)) {
window.location.href = `https://www.gitpod.io${pathname}${window.location.search}`;
return;
}
minimalMode = true;
}

// Not in minimal mode, but still handle website slugs
if (isWebsiteSlug(window.location.pathname)) {
window.location.host = "www.gitpod.io";
return;
// Check local storage override
try {
if (localStorage.getItem(MINIMAL_MODE_OVERRIDE_KEY) === "true") {
minimalMode = true;
}
} catch {
// localStorage might not be available
}

if (minimalMode) {
handleMinimalGitpodIoMode();
return;
}

// Boot full React app
Expand Down
3 changes: 2 additions & 1 deletion components/dashboard/src/minimal-login.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
See License.AGPL.txt in the project root for license information.
Minimal login page for gitpod.io when minimal mode is enabled.
This page is loaded by index.tsx when the minimal_gitpod_io_mode flag is active.
This is a complete HTML document for easier editing and preview.
index.tsx extracts only the body content using DOMParser.
-->
<html lang="en">
<head>
Expand Down
2 changes: 1 addition & 1 deletion dev/preview/workflow/preview/deploy-gitpod.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ GITPOD_IMAGE_PULL_SECRET_NAME="image-pull-secret";
GITPOD_PROXY_SECRET_NAME="proxy-config-certificates";
GITPOD_ANALYTICS="${GITPOD_ANALYTICS:-}"
GITPOD_WORKSPACE_FEATURE_FLAGS="${GITPOD_WORKSPACE_FEATURE_FLAGS:-}"
GITPOD_WITH_DEDICATED_EMU="${GITPOD_WITH_DEDICATED_EMU:-false}"
GITPOD_WITH_DEDICATED_EMU="${GITPOD_WITH_DEDICATED_EMU:-true}"
PREVIEW_GCP_PROJECT="gitpod-dev-preview"


Expand Down
Loading