Skip to content
Draft
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
4 changes: 3 additions & 1 deletion astro/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { staticApiGuard } from "./src/integrations/staticApiGuard.ts";

const websitesModules = resolveWebsitesModulesPath(import.meta.url);
const hugoSite = fileURLToPath(new URL("../hugo", import.meta.url));
const shared = fileURLToPath(new URL("../shared", import.meta.url));
const astroSite = fileURLToPath(new URL(".", import.meta.url));

const hugoDevPort = 1313;
Expand Down Expand Up @@ -112,7 +113,7 @@ export default defineConfig({
],
server: {
fs: {
allow: [astroSite, hugoSite, websitesModules],
allow: [astroSite, hugoSite, shared, websitesModules],
},
...(IS_PROXIED && {
origin: `http://localhost:${PROXY_PORT}`,
Expand All @@ -127,6 +128,7 @@ export default defineConfig({
resolve: {
alias: {
"@hugo-site": hugoSite,
"@shared": shared,
"@websites-modules": websitesModules,
"@layouts": fileURLToPath(new URL("./src/layouts", import.meta.url)),
"@components": fileURLToPath(
Expand Down
15 changes: 6 additions & 9 deletions astro/src/components/Alert/Alert.astro
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
---
import styles from "./Alert.module.css";
import { classListFactory } from "@lib/cssUtils/classListFactory";
import { i18n } from "@lib/i18n/i18n";
import { DEFAULT_LOCALE, isLocale } from "@lib/i18n/locale";
import { useTranslations } from "@lib/i18n/i18n";
interface Props {
level?: "info" | "danger" | "warning" | "tip";
}
const { level = "info" } = Astro.props;
const lang = isLocale(Astro.currentLocale)
? Astro.currentLocale
: DEFAULT_LOCALE;
const translate = useTranslations(Astro.currentLocale);
const labels: Record<NonNullable<Props["level"]>, string> = {
info: i18n("alert_note", lang),
danger: i18n("alert_caution", lang),
warning: i18n("alert_warning", lang),
tip: i18n("alert_tip", lang),
info: translate("alert_note"),
danger: translate("alert_caution"),
warning: translate("alert_warning"),
tip: translate("alert_tip"),
};
const label = labels[level];
Expand Down
5 changes: 3 additions & 2 deletions astro/src/components/ApiCodeExample/ApiCodeExample.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ExpandChevron from "@components/ExpandChevron/ExpandChevron.astro";
import styles from "./ApiCodeExample.module.css";
import { classListFactory } from "@lib/cssUtils/classListFactory";
import { generateElementId } from "@lib/componentUtils/generateElementId";
import { i18n } from "@lib/i18n/i18n";
import { useTranslations } from "@lib/i18n/i18n";

const cl = classListFactory(styles);

Expand All @@ -29,6 +29,7 @@ interface Props {
}

const { examples } = Astro.props;
const translate = useTranslations(Astro.currentLocale);

const groupId = generateElementId("api-code-example");
const labels = examples.map((ex) => ex.label);
Expand All @@ -38,7 +39,7 @@ const panelIds = examples.map((_, i) => `${groupId}-panel-${i}`);
{
examples.length > 0 && (
<div class={cl("api-code-example")}>
<h3 class={cl("api-code-example__heading")}>{i18n("code_example")}</h3>
<h3 class={cl("api-code-example__heading")}>{translate("code_example")}</h3>

<Tabs id={groupId} variant="pills" labels={labels} panelIds={panelIds}>
{examples.map((ex, tabIdx) => (
Expand Down
7 changes: 4 additions & 3 deletions astro/src/components/ApiEndpoint/ApiEndpoint.astro
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { getDefaultRegions } from "@lib/api/regionResolver";
import { renderMarkdownInline } from "@lib/api/markdownRenderer";
import styles from "./ApiEndpoint.module.css";
import { classListFactory } from "@lib/cssUtils/classListFactory";
import { i18n } from "@lib/i18n/i18n";
import { useTranslations } from "@lib/i18n/i18n";

const allRegions = getDefaultRegions();
const cl = classListFactory(styles);
Expand Down Expand Up @@ -50,6 +50,7 @@ interface Props {
}

const { data: dataJson } = Astro.props;
const translate = useTranslations(Astro.currentLocale);

let ep: EndpointData | null = null;
try {
Expand Down Expand Up @@ -122,7 +123,7 @@ const hasParams =
</div>

{/* Description — rendered as slot content from the parent page */}
{ep.description && <h3>{i18n("overview")}</h3>}
{ep.description && <h3>{translate("overview")}</h3>}
<slot />

{/* Permissions */}
Expand All @@ -146,7 +147,7 @@ const hasParams =
{/* Arguments */}
{hasParams && (
<div class={cl("api-endpoint__section")}>
<h3>{i18n("arguments")}</h3>
<h3>{translate("arguments")}</h3>
{ep.pathParams && ep.pathParams.length > 0 && (
<ApiSchemaTable fields={ep.pathParams} />
)}
Expand Down
6 changes: 2 additions & 4 deletions astro/src/components/ApiPageHeader/ApiPageHeader.astro
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
---
import CopyPageButtonIsland from "@components/CopyPageButton/CopyPageButtonIsland.astro";
import { classListFactory } from "@lib/cssUtils/classListFactory";
import type { Locale } from "@lib/i18n/locale";
import styles from "./ApiPageHeader.module.css";

const cl = classListFactory(styles);

interface Props {
title: string;
lang: Locale;
}

const { title, lang } = Astro.props;
const { title } = Astro.props;
---

<div class={cl("api-page-header")}>
<h1 class={cl("api-page-header__title")}>{title}</h1>
<div class={cl("api-page-header__copy")}>
<CopyPageButtonIsland lang={lang} />
<CopyPageButtonIsland />
</div>
</div>
7 changes: 4 additions & 3 deletions astro/src/components/ApiResponse/ApiResponse.astro
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { renderMarkdownInline } from "@lib/api/markdownRenderer";
import styles from "./ApiResponse.module.css";
import { classListFactory } from "@lib/cssUtils/classListFactory";
import { generateElementId } from "@lib/componentUtils/generateElementId";
import { i18n } from "@lib/i18n/i18n";
import { useTranslations } from "@lib/i18n/i18n";

const cl = classListFactory(styles);

Expand All @@ -29,6 +29,7 @@ interface Props {
}

const { responses } = Astro.props;
const translate = useTranslations(Astro.currentLocale);

const outerGroupId = generateElementId("api-response");
const outerLabels = responses.map((r) => r.statusCode);
Expand All @@ -42,7 +43,7 @@ const innerPanelIds = responses.map((_, i) => [
{
responses.length > 0 && (
<div class={cl("api-response")}>
<h3 class={cl("api-response__heading")}>{i18n("response")}</h3>
<h3 class={cl("api-response__heading")}>{translate("response")}</h3>

<Tabs
id={outerGroupId}
Expand Down Expand Up @@ -70,7 +71,7 @@ const innerPanelIds = responses.map((_, i) => [
<Tabs
id={`${outerGroupId}-inner-${i}`}
variant="pills"
labels={[i18n("model"), i18n("example")]}
labels={[translate("model"), translate("example")]}
panelIds={innerPanelIds[i]}
>
<TabPanel id={innerPanelIds[i][0]} isActive>
Expand Down
9 changes: 5 additions & 4 deletions astro/src/components/ApiSchemaTable/ApiSchemaTable.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import SchemaFieldRow from "./SchemaFieldRow.astro";
import styles from "./ApiSchemaTable.module.css";
import { classListFactory } from "@lib/cssUtils/classListFactory";
import { generateElementId } from "@lib/componentUtils/generateElementId";
import { i18n } from "@lib/i18n/i18n";
import { useTranslations } from "@lib/i18n/i18n";

const cl = classListFactory(styles);

Expand All @@ -16,6 +16,7 @@ interface Props {
}

const { fields, title, showExpandAll = true } = Astro.props;
const translate = useTranslations(Astro.currentLocale);

const tableId = generateElementId("schema-table");
const expandAllId = `${tableId}-expand-all`;
Expand Down Expand Up @@ -63,10 +64,10 @@ const showToolbar = showExpandAll && anyExpandable;
}
<div class={cl("schema-table__table")}>
<div class={cl("schema-table__columns")}>
<div class={cl("schema-table__columns-name")}>{i18n("name")}</div>{" "}
<div class={cl("schema-table__columns-type")}>{i18n("type")}</div>{" "}
<div class={cl("schema-table__columns-name")}>{translate("name")}</div>{" "}
<div class={cl("schema-table__columns-type")}>{translate("type")}</div>{" "}
<div class={cl("schema-table__columns-description")}>
{i18n("description")}
{translate("description")}
</div>
</div>
{fields.map((field) => <SchemaFieldRow field={field} depth={0} />)}
Expand Down
12 changes: 7 additions & 5 deletions astro/src/components/ApiSideNav/ApiSideNav.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { classListFactory } from "@lib/cssUtils/classListFactory";
import SearchBar, {
type SearchBarLabels,
} from "@components/SearchBar/SearchBar";
import { DEFAULT_LOCALE, localizedHref, type Locale } from "@lib/i18n/locale";
import { localizedHref, resolveLocale } from "@lib/i18n/locale";
import { useTranslations } from "@lib/i18n/i18n";
import ScrollActiveIntoView from "@components/ScrollActiveIntoView/ScrollActiveIntoView.astro";
import type { OverviewPage } from "@lib/api/overviewPages";

Expand All @@ -16,7 +17,6 @@ interface Props {
overviewPages?: OverviewPage[];
isOverviewSection?: boolean;
activeOverviewPageSlug?: string;
lang?: Locale;
}

const {
Expand All @@ -26,11 +26,13 @@ const {
overviewPages = [],
isOverviewSection = false,
activeOverviewPageSlug,
lang = DEFAULT_LOCALE,
} = Astro.props;
// `lang` is still needed for the hrefs below; `translate` covers the labels.
const lang = resolveLocale(Astro.currentLocale);
const translate = useTranslations(lang);
const cl = classListFactory(styles);

const overviewLabel = "Overview";
const overviewLabel = translate("overview");
const overviewHref = localizedHref(lang, "/api/latest/");

// TODO: replace hardcoded English with i18n() once authoritative translation
Expand All @@ -45,7 +47,7 @@ const searchLabels: SearchBarLabels = {

<nav class={cl("api-side-nav")}>
<a href={localizedHref(lang, "/")} class={cl("api-side-nav__title")}>
Datadog Docs&nbsp;&nbsp;<span class={cl("api-side-nav__title-api")}
{translate("datadog_docs")}&nbsp;&nbsp;<span class={cl("api-side-nav__title-api")}
>API</span
>
</a>
Expand Down
5 changes: 3 additions & 2 deletions astro/src/components/CodeBlock/CodeBlock.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { CollapseToggle, type CollapseToggleLabels } from "./CollapseToggle";
import styles from "./CodeBlock.module.css";
import { classListFactory } from "@lib/cssUtils/classListFactory";
import { generateElementId } from "@lib/componentUtils/generateElementId";
import { i18n } from "@lib/i18n/i18n";
import { useTranslations } from "@lib/i18n/i18n";

const cl = classListFactory(styles);

Expand All @@ -27,6 +27,7 @@ const {
collapsible = false,
disable_copy = false,
} = Astro.props;
const translate = useTranslations(Astro.currentLocale);

let highlightedCode = "";
if (content) {
Expand All @@ -50,7 +51,7 @@ const containerClass = wrap
// keys exist for these strings in the Hugo i18n bundle.
const copyLabels: CopyButtonLabels = {
"Copy code": "Copy code",
Copy: i18n("copy"),
Copy: translate("copy"),
"Copied!": "Copied!",
};

Expand Down
11 changes: 5 additions & 6 deletions astro/src/components/CopyPageButton/CopyPageButtonIsland.astro
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
---
import { CopyPageButton, type CopyPageButtonVariant } from './CopyPageButton';
import { i18n } from '@lib/i18n/i18n';
import type { Locale } from '@lib/i18n/locale';
import { useTranslations } from '@lib/i18n/i18n';
interface Props {
lang: Locale;
variant?: CopyPageButtonVariant;
}
const { lang, variant = 'default' } = Astro.props;
const { variant = 'default' } = Astro.props;
const translate = useTranslations(Astro.currentLocale);
// `copied` is the authoritative Hugo key for the post-copy state. "Copy page"
// has no Hugo key yet — pass the literal English as the lookup key so it
// surfaces automatically once translators add it.
const labels = {
'Copy page': i18n('Copy page', lang),
'Copied': i18n('copied', lang),
'Copy page': translate('Copy page'),
'Copied': translate('copied'),
};
---

Expand Down
36 changes: 21 additions & 15 deletions astro/src/components/Footer/Footer.astro
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,44 @@ import FreeTrialModal from "./FreeTrialModal.tsx";
import SocialIcon from "./SocialIcon.astro";
import SvgIcon from "../SvgIcon/SvgIcon.astro";
import { getFooterData } from "@lib/componentUtils/footerMenus.ts";
import { i18n } from "@lib/i18n/i18n";
import { useTranslations } from "@lib/i18n/i18n";
import {
getTranslations,
getLanguageNames,
getNativeLabel,
type LangCode,
} from "@lib/i18n/languageNames";
import { LOCALES, localizedHref, stripLocalePrefix } from "@lib/i18n/locale";
import {
LOCALES,
localizedHref,
resolveLocale,
stripLocalePrefix,
} from "@lib/i18n/locale";

const cl = classListFactory(styles);

const footer = getFooterData();

const year = new Date().getFullYear();

// Language selector — Astro's i18n routing handles the actual locale switch,
// so each link is a real localized URL. The footer renders all supported
// locales; the toolbar instance reuses the same Preact component.
const { lang: footerLang, rest: footerLocaleless } = stripLocalePrefix(
Astro.url.pathname,
);
const currentLang: LangCode = footerLang;
const translate = getTranslations(currentLang);
const { rest: footerLocaleless } = stripLocalePrefix(Astro.url.pathname);
const currentLang: LangCode = resolveLocale(Astro.currentLocale);
const translate = useTranslations(currentLang);
const footer = getFooterData(currentLang);

// Localized *language names* for the selector — distinct from `translate`,
// which resolves i18n keys.
const languageName = getLanguageNames(currentLang);
const currentLangOption = {
code: currentLang,
primary: getNativeLabel(currentLang),
secondary: translate(currentLang),
href: localizedHref(footerLang, footerLocaleless),
secondary: languageName(currentLang),
href: localizedHref(currentLang, footerLocaleless),
};
const alternates = LOCALES.filter((c) => c !== currentLang).map((code) => ({
code,
primary: getNativeLabel(code),
secondary: translate(code),
secondary: languageName(code),
href: localizedHref(code, footerLocaleless),
}));

Expand All @@ -67,7 +73,7 @@ const caretIconHtml = inlineSvg("arrow.svg", "#ffffff", "16px");

// Free-trial modal config — swap iframeSrc when we move off app.datadoghq.com/signup.
const freeTrialHref = "https://app.datadoghq.com/signup";
const freeTrialLabel = i18n("free_trial");
const freeTrialLabel = translate("free_trial");

---

Expand All @@ -88,7 +94,7 @@ const freeTrialLabel = i18n("free_trial");
<span>{freeTrialLabel}</span>
</a>

<p class={cl("footer__download-app")}>{i18n("download_mobile_app")}</p>
<p class={cl("footer__download-app")}>{translate("download_mobile_app")}</p>

<div class={cl("footer__download-badges")}>
<a
Expand Down
Loading