import type { Dashboard } from "@dci/core";
import { ExternalLink } from "lucide-react";
import type { Metadata } from "next";
import Link from "next/link";
import { EventList } from "@/components/event-list";
import { CapacityOverTime } from "@/components/home/charts";
import { HeroSearch } from "@/components/home/hero";
import { MapPreview } from "@/components/home/map-preview";
import { PipelineFunnel } from "@/components/home/pipeline-funnel";
import { PulseBlock } from "@/components/home/pulse";
import { GlobalTicker } from "@/components/home/ticker";
import { ProjectList } from "@/components/project-list";
import { AiMark, Badge } from "@/components/ui/badge";
import { MoreLink } from "@/components/ui/button";
import { Page, Section } from "@/components/ui/card";
import { BarList } from "@/components/ui/charts";
import { CountryFlag } from "@/components/ui/country-flag";
import { RelativeTime } from "@/components/ui/relative-time";
import { SourceBadge } from "@/components/ui/source-badge";
import { EmptyState, OfflineNotice } from "@/components/ui/states";
import { TBody, THead, Table, Td, Th, Tr } from "@/components/ui/table";
import { api } from "@/lib/api";
import { fmtDate, fmtInt, fmtMw, fmtPct, splitMw } from "@/lib/format";
import { isSiteScopeLabel } from "@/lib/labels";
import { routes } from "@/lib/routes";
export const revalidate = 60;
export const metadata: Metadata = {
title: { absolute: "DataCenterIndex — Global data center infrastructure, indexed and versioned" },
description: "Facilities, operators, cloud regions, markets, countries, projects, power and connectivity — every figure sourced, versioned and tracked in a live change feed. Known operational capacity, construction pipeline, AI expansion, coverage.",
alternates: { canonical: "/" },
};
function Cell({ label, value, unit, note, href }: { label: string; value: string; unit?: string; note?: string; href?: string }) {
const body = (
<>
{label}
{value}
{unit && {unit} }
{note && {note}
}
>
);
return href ? (
{body}
) : (
{body}
);
}
export default async function HomePage() {
const r0 = await api.dashboard();
// tolerate an older API payload (image builds prerender against the live API): every 2.0 block is optional
const r = r0.ok && r0.data ? { ...r0, data: { ...r0.data, pulse: r0.data.pulse ?? null, fastestGrowingMetros: r0.data.fastestGrowingMetros ?? [], majorProjects: r0.data.majorProjects ?? [], operatorExpansion: r0.data.operatorExpansion ?? [], powerEvents: r0.data.powerEvents ?? [], gridConstraints: r0.data.gridConstraints ?? [], coverage: r0.data.coverage ?? null, ingestion: r0.data.ingestion ?? null } as typeof r0.data } : r0;
const d: Dashboard | null = r.ok ? r.data : null;
const stats = d?.stats ?? null;
const cov = d?.coverage ?? null;
const ing = d?.ingestion ?? null;
const major = (d?.majorProjects ?? []).filter((p) => p.plannedMw !== null && p.plannedMw >= 100 && (p.capacityScope == null || isSiteScopeLabel(p.capacityScope)));
const aiMw = splitMw(d?.aiExpansion.plannedMw);
return (
{/* ---------------------------------------------------------------- hero + live map */}
Live index
{ing?.lastRunAt && (
· last ingestion
)}
Global data center infrastructure
The structured index of facilities, campuses, operators, cloud regions, markets, projects, power and connectivity — every figure published, sourced, versioned and tracked in a live change feed.
{!r.ok && }
{stats ? `${fmtInt(stats.facilities)} facilities · ${fmtInt(stats.countries)} countries · ${fmtInt(stats.metros)} markets` : "Clustered by market"}
size = known MW · hollow ring = city-level location
{/* ---------------------------------------------------------------- what changed today */}
Full pulse}>
{d?.pulse ? : }
{/* ---------------------------------------------------------------- AI expansion */}
AI infrastructure expansion
}
description="Facilities and projects with AI / HPC evidence (confirmed, likely or associated) — published MW only."
aside={AI index }
>
|
|
|
{/* ---------------------------------------------------------------- construction pipeline */}
{/* ---------------------------------------------------------------- fastest-growing markets */}
Markets}>
{d?.fastestGrowingMetros.length ? (
Market
Announced
In constr.
Announced MW
Entrants
Grid ev.
{d.fastestGrowingMetros.slice(0, 8).map((m) => (
{m.name}
{fmtInt(m.momentum.projectsAnnounced)}
{fmtInt(m.momentum.projectsEnteredConstruction)}
{m.momentum.announcedMw !== null ? `≈ ${fmtMw(m.momentum.announcedMw)}` : "—"}
{fmtInt(m.momentum.newEntrants.length)}
{fmtInt(m.momentum.gridEvents)}
))}
) : (
)}
{/* ---------------------------------------------------------------- major projects */}
{/* ---------------------------------------------------------------- operator expansion */}
Operators}>
{d?.operatorExpansion.length ? (
{d.operatorExpansion.slice(0, 8).map((o) => (
{o.operator.name}
{o.newCountries.length ? (
{o.newCountries.slice(0, 6).map((c) => (
))}
{o.newCountries.length > 6 && +{o.newCountries.length - 6} }
) : null}
{o.newMetros.length > 0 && {o.newMetros.slice(0, 3).join(", ")}{o.newMetros.length > 3 ? ` +${o.newMetros.length - 3}` : ""} }
{fmtInt(o.newCountries.length)} countries
{fmtInt(o.newMetros.length)} markets · {fmtInt(o.projects12m)} prj
))}
) : (
)}
{/* ---------------------------------------------------------------- power / grid */}
Power & grid}>
{d?.gridConstraints.length ? (
Grid constraints
{d.gridConstraints.slice(0, 4).map((g) => (
{g.kind.replace(/_/g, " ")}
{g.title}
{g.sourceKind && }
{fmtDate(g.effectiveDate)}
))}
) : null}
{/* ---------------------------------------------------------------- cloud / connectivity */}
Connectivity}>
|
|
|
Largest markets · known operational MW
{d?.topMetros?.length ? (
({ rank: m.rank, label: {m.name} , value: m.value, href: m.href || routes.market(m.slug), coverage: m.coverage, secondary: m.coverage != null ? `${fmtPct(m.coverage)} MW coverage` : undefined, display: fmtMw(m.value) }))}
/>
) : (
)}
{/* ---------------------------------------------------------------- capacity over time */}
{/* ---------------------------------------------------------------- coverage · transparency · ingestion */}
Data coverage
Coverage
{cov ? (
{[
["Capacity (MW) published", cov.capacityCoverage],
["Operator known", cov.operatorCoverage],
["Precise location", cov.preciseLocationCoverage],
["Any location", cov.anyLocationCoverage],
["Status known", cov.statusCoverage],
["Opening date known", cov.openingDateCoverage],
["Multiple sources", cov.multiSourceCoverage],
["Connectivity known", cov.connectivityCoverage],
].map(([k, v]) => (
{k}
{fmtPct(v as number, (v as number) < 0.1 ? 1 : 0)}
))}
) : (
)}
Share of {cov ? fmtInt(cov.facilities) : ""} indexed facilities. Gaps are shown, never filled.
Source transparency
Sources
|
|
|
|
Every field carries its source, dates, confidence and extraction method; every figure opens an evidence drawer with the supporting sentence.{" "}
Methodology
{" "}
·{" "}
Downloads
{" "}
·{" "}
API
Latest ingestion
Live feed
{ing ? (
<>
|
|
|
|
{fmtInt(ing.events24h)} events detected in 24 h. Pipeline: discover → fetch → archive → extract → normalize → reconcile → validate → version → detect changes → publish.{" "}
Crawler policy
>
) : (
)}
{stats ? <>MW figures are published for {fmtPct(stats.mwCoverage)} of indexed facilities; every total is a lower bound computed from sourced figures — nothing is extrapolated or imputed. > : <>Totals are lower bounds computed from sourced figures only; nothing is extrapolated. >}
How the index is built
.
);
}