Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
1e7c9a5
feat(home): offer VS Code alongside Docker in the quick start
guanzhousongmicrosoft Aug 24, 2026
4fde31b
Merge latest main into homepage quick start PR
guanzhousongmicrosoft Sep 10, 2026
4b60822
Refresh VS Code quick start for released local setup
guanzhousongmicrosoft Sep 10, 2026
95c246a
Enable JSX rendering in homepage regression tests
guanzhousongmicrosoft Sep 10, 2026
cb4c620
Name the link confirmation button in the VS Code quick start
guanzhousongmicrosoft Sep 10, 2026
0d56580
Make the quick start readable to someone who has not seen the wizard
guanzhousongmicrosoft Sep 10, 2026
bf4bcf8
Merge remote-tracking branch 'origin/main' into dev/guanzhousong/hero…
guanzhousongmicrosoft Sep 10, 2026
33f4887
Fix the guide the VS Code tab opens, and make the hero command runnable
guanzhousongmicrosoft Sep 10, 2026
5a03375
Make the VS Code tab the easy path
guanzhousongmicrosoft Sep 11, 2026
2c1eac7
Show the retry line late, and tighten the VS Code caption
guanzhousongmicrosoft Sep 11, 2026
8e51bad
Derive guide anchors in one place, and move the retry line below the …
guanzhousongmicrosoft Sep 11, 2026
a25f97e
Frame local quick start as manual and guided setup
GuanzhouSong Sep 22, 2026
415dbdd
Simplify homepage quick-start guidance
GuanzhouSong Sep 23, 2026
ad134e4
Point Linux users without Docker to packages from the quick start
guanzhousongmicrosoft Sep 23, 2026
ee02adf
Move the Linux packages link below the quick start and open its guide
guanzhousongmicrosoft Sep 23, 2026
6d90d45
Scope the retry-status check to the guided panel
guanzhousongmicrosoft Sep 23, 2026
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
4 changes: 2 additions & 2 deletions app/components/Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Link from "next/link";
import { useMemo } from 'react';
import type { ReactElement } from 'react';
import Code from './Code';
import { kebabCase } from 'change-case';
import { headingAnchor } from '../lib/docsAnchors';
import { resolveMarkdownLink } from '../lib/markdownLinks';

interface MarkdownProps {
Expand Down Expand Up @@ -43,7 +43,7 @@ export default function Markdown({ content, sourcePath }: MarkdownProps) {

elements.push(
<div key={`section-${index}`} className="bg-neutral-800/50 backdrop-blur-sm rounded-lg border border-neutral-700/50 p-6">
<a className="invisible scroll-mt-24" id={kebabCase(title)} />
<a className="invisible scroll-mt-24" id={headingAnchor(title)} />
<h2 className="text-2xl font-semibold text-white mb-4">
{title}
</h2>
Expand Down
182 changes: 182 additions & 0 deletions app/components/QuickStartTabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
"use client";

import Link from "next/link";
import { useRef, useState } from "react";
import CommandSnippet from "./CommandSnippet";

type QuickStartTabsProps = {
dockerCommand: string;
vscodeDeepLinkUrl: string;
vscodeMarketplaceUrl: string;
dockerDocsUrl: string;
vscodeDocsUrl: string;
};

const TABS = [
{ id: "command", label: "Docker command", description: "Run it yourself" },
{ id: "guided", label: "Guided setup", description: "VS Code extension" },
] as const;

type TabId = (typeof TABS)[number]["id"];

export default function QuickStartTabs({
dockerCommand,
vscodeDeepLinkUrl,
vscodeMarketplaceUrl,
dockerDocsUrl,
vscodeDocsUrl,
}: QuickStartTabsProps) {
const [activeTab, setActiveTab] = useState<TabId>("command");
const tabRefs = useRef<Partial<Record<TabId, HTMLButtonElement | null>>>({});

const selectTab = (id: TabId) => {
setActiveTab(id);
tabRefs.current[id]?.focus();
};

const onTabKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {
const currentIndex = TABS.findIndex((tab) => tab.id === activeTab);

switch (event.key) {
case "ArrowRight":
case "ArrowLeft": {
event.preventDefault();
const delta = event.key === "ArrowRight" ? 1 : -1;
selectTab(TABS[(currentIndex + delta + TABS.length) % TABS.length].id);
break;
}
case "Home":
event.preventDefault();
selectTab(TABS[0].id);
break;
case "End":
event.preventDefault();
selectTab(TABS[TABS.length - 1].id);
break;
default:
break;
}
};

return (
<div>
<div
role="tablist"
aria-label="Ways to set up DocumentDB locally"
className="mb-4 grid grid-cols-2 gap-1 rounded-2xl border border-neutral-700 bg-neutral-900/80 p-1"
>
{TABS.map((tab) => {
const isActive = tab.id === activeTab;

return (
<button
key={tab.id}
ref={(element) => {
tabRefs.current[tab.id] = element;
}}
type="button"
role="tab"
id={`quickstart-tab-${tab.id}`}
aria-selected={isActive}
aria-controls={`quickstart-panel-${tab.id}`}
tabIndex={isActive ? 0 : -1}
onClick={() => selectTab(tab.id)}
onKeyDown={onTabKeyDown}
className={`min-h-14 min-w-0 rounded-xl px-3 py-3 text-left text-sm font-semibold transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-300 ${
isActive
? "bg-neutral-700 text-white"
: "text-gray-300 hover:text-white"
}`}
>
{tab.label}
<span
className={`mt-1 block text-xs font-normal ${
isActive ? "text-gray-300" : "text-gray-400"
}`}
>
{tab.description}
</span>
</button>
);
})}
</div>

<div
role="tabpanel"
id="quickstart-panel-command"
aria-labelledby="quickstart-tab-command"
hidden={activeTab !== "command"}
>
<p className="mb-4 text-sm leading-6 text-gray-300">
Replace the username and password, then run the command.
</p>
<CommandSnippet command={dockerCommand} label="bash" />
<p className="mt-4 text-sm leading-6 text-gray-300">
Then connect with your preferred client.
</p>
<div className="mt-3 text-sm">
<Link
href={dockerDocsUrl}
className="font-semibold text-blue-300 transition-colors hover:text-blue-200"
>
Docker setup guide
</Link>
</div>
</div>

<div
role="tabpanel"
id="quickstart-panel-guided"
aria-labelledby="quickstart-tab-guided"
hidden={activeTab !== "guided"}
>
<p className="mb-4 text-sm leading-6 text-gray-300">
The VS Code extension creates your local database, generates
credentials, and saves a connection.
</p>
<a
href={vscodeDeepLinkUrl}
aria-describedby="quickstart-vscode-setup-caption"
className="inline-flex w-full items-center justify-center rounded-md bg-blue-500 px-6 py-3 text-sm font-semibold text-white transition-colors hover:bg-blue-400 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-300 sm:w-auto"
>
Set up in VS Code
</a>
<p
id="quickstart-vscode-setup-caption"
className="mt-3 text-sm leading-6 text-gray-400"
>
Requires{" "}
<Link
href="https://code.visualstudio.com/"
target="_blank"
rel="noopener noreferrer"
className="font-semibold text-blue-300 transition-colors hover:text-blue-200"
>
VS Code
</Link>
. You may be prompted to install the{" "}
<Link
href={vscodeMarketplaceUrl}
target="_blank"
rel="noopener noreferrer"
className="font-semibold text-blue-300 transition-colors hover:text-blue-200"
>
DocumentDB extension
</Link>
.
</p>
<p className="mt-4 text-sm leading-6 text-gray-300">
When setup finishes, select Open Connection.
</p>
<div className="mt-4 text-sm">
<Link
href={vscodeDocsUrl}
className="font-semibold text-blue-300 transition-colors hover:text-blue-200"
>
VS Code setup guide
</Link>
</div>
</div>
</div>
);
}
12 changes: 12 additions & 0 deletions app/lib/docsAnchors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { kebabCase } from 'change-case';

/**
* Anchor id for a guide H2, exactly as Markdown.tsx emits it. Anything that links into a
* guide section derives the fragment here, so the renderer and the link cannot disagree.
*/
export function headingAnchor(title: string): string {
return kebabCase(title);
}

export const vscodeExistingConnectionSectionTitle = 'Connect an existing instance';
export const vscodeExistingConnectionSectionAnchor = headingAnchor(vscodeExistingConnectionSectionTitle);
76 changes: 25 additions & 51 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import Image from "next/image";
import Link from "next/link";
import CommandSnippet from "./components/CommandSnippet";
import { documentdbKubernetesOperatorQuickStartUrl } from "./services/externalLinks";
import QuickStartTabs from "./components/QuickStartTabs";
import {
documentdbKubernetesOperatorQuickStartUrl,
documentdbVsCodeExtensionMarketplaceUrl,
documentdbVsCodeLocalQuickStartDeepLink,
} from "./services/externalLinks";
import { getMetadata } from "./services/metadataService";
import {
documentdbGitHubForks,
Expand Down Expand Up @@ -34,25 +38,10 @@ type Capability = {
};

const quickRunCommand = `docker run -dt --name documentdb \\
-p 10260:10260 \\
-p 127.0.0.1:10260:10260 \\
ghcr.io/documentdb/documentdb/documentdb-local:latest \\
--username <YOUR_USERNAME> \\
--password <YOUR_PASSWORD>`;

const quickStartSteps = [
{
step: "01",
description: "Run DocumentDB Local with Docker.",
},
{
step: "02",
description: "Connect on port 10260 with your app, shell, or client.",
},
{
step: "03",
description: "Continue with the docs or Linux packages for the setup you need.",
},
];
--username '<YOUR_USERNAME>' \\
--password '<YOUR_PASSWORD>'`;

const kubernetesOperatorEntryPoints = [
{
Expand Down Expand Up @@ -316,7 +305,7 @@ export default function Home() {
<section className="relative overflow-hidden border-b border-neutral-800 bg-gradient-to-b from-neutral-800 via-neutral-900 to-black">
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top_right,_rgba(59,130,246,0.2),_transparent_45%),radial-gradient(circle_at_bottom_left,_rgba(16,185,129,0.18),_transparent_45%)]" />
<div className="relative mx-auto max-w-7xl px-4 py-14 sm:px-6 sm:py-20 lg:px-8 lg:py-24">
<div className="grid items-center gap-8 lg:gap-10 xl:grid-cols-[1.15fr_0.85fr]">
<div className="grid items-start gap-8 lg:gap-10 xl:grid-cols-[1.15fr_0.85fr]">
<div className="min-w-0">
<p className="mb-3 text-xs font-semibold uppercase tracking-[0.24em] text-blue-300">
Open source document database
Expand Down Expand Up @@ -372,43 +361,28 @@ export default function Home() {
Quick start
</span>
<h2 className="mt-4 text-xl font-semibold text-white sm:text-2xl">
Run locally with Docker
Run DocumentDB locally
</h2>
<p className="mt-2 text-sm leading-6 text-gray-400">
Start DocumentDB Local with Docker, then connect on port
10260.
Both options require Docker.
</p>
</div>
<CommandSnippet command={quickRunCommand} label="Docker" />
<ol className="mt-5 overflow-hidden rounded-2xl border border-neutral-800/80 bg-neutral-900/50">
{quickStartSteps.map((item) => (
<li
key={item.step}
className="grid grid-cols-[auto_1fr] items-center gap-3 border-t border-neutral-800/80 px-4 py-3.5 first:border-t-0"
>
<span className="inline-flex h-7 w-7 items-center justify-center rounded-full border border-blue-400/30 bg-blue-500/10 text-[11px] font-semibold text-blue-200">
{item.step}
</span>
<p className="text-sm leading-6 text-gray-300">
{item.description}
</p>
</li>
))}
</ol>
<div className="mt-4 flex flex-col gap-2 text-sm sm:flex-row sm:flex-wrap sm:items-center sm:gap-4">
<Link
href="/docs/getting-started/docker"
className="font-semibold text-blue-300 transition-colors hover:text-blue-200"
>
Docker quick start
</Link>
<QuickStartTabs
dockerCommand={quickRunCommand}
vscodeDeepLinkUrl={documentdbVsCodeLocalQuickStartDeepLink}
vscodeMarketplaceUrl={documentdbVsCodeExtensionMarketplaceUrl}
dockerDocsUrl="/docs/getting-started/docker"
vscodeDocsUrl="/docs/getting-started/vscode-quickstart"
/>
<p className="mt-6 border-t border-neutral-800 pt-4 text-sm leading-6 text-gray-400">
Prefer to install directly on Linux?{" "}
<Link
href="/packages"
className="font-semibold text-gray-300 transition-colors hover:text-white"
href="/docs/getting-started/packages"
className="whitespace-nowrap font-semibold text-blue-300 transition-colors hover:text-blue-200"
>
Download packages
Linux packages guide
</Link>
</div>
</p>
</div>
</div>
</div>
Expand Down
Loading
Loading