${item.name}
${item.description || text.hostCard?.fallbackDesc || ""}
${root}
${openaiBase}
${geminiBase}
${antigravityBase}${antigravityGeminiBase}
${item.description || text.hostCard?.fallbackDesc || ""}
${root}
${openaiBase}
${geminiBase}
${antigravityBase}${antigravityGeminiBase}
/docs/api.html`,
"html",
);
replaceNodeContent(".hero h1", text.hero?.title || "", "text");
replaceNodeContent(".hero-copy", text.hero?.copyHtml || "", "html");
replaceAllText(".hero-actions a", text.hero?.actions || []);
replaceAllText(".hero-stat .label", text.hero?.statLabels || []);
replaceNodeContent(
".hero-stat:nth-child(2) .value",
text.hero?.keyPathHtml || "",
"html",
);
replaceNodeContent(
".hero-stat:nth-child(3) .value",
text.hero?.placement || "",
"text",
);
replaceNodeContent(
".hero-stat:nth-child(4) .value",
text.hero?.protocols || "",
"text",
);
replaceNodeContent(".sidebar h2", text.sidebar?.title || "", "text");
replaceAllText(".sidebar a", text.sidebar?.links || []);
replaceNodeContent("#quickstart h2", text.quickstart?.title || "", "text");
replaceNodeContent("#quickstart .section-desc", text.quickstart?.descHtml || "", "html");
replaceAllText("#quickstart .card h3", (text.quickstart?.cards || []).map((item) => item.title));
replaceAllHtml("#quickstart .card p", (text.quickstart?.cards || []).map((item) => item.bodyHtml));
replaceNodeContent("#quickstart .note", text.quickstart?.noteHtml || "", "html");
replaceNodeContent("#ccswitch h2", text.ccswitch?.title || "", "text");
replaceNodeContent("#ccswitch > .section-desc", text.ccswitch?.descHtml || "", "html");
replaceAllText("#ccswitch .grid-2 .card h3", [
text.ccswitch?.cards?.download?.title || "",
text.ccswitch?.cards?.oneClick?.title || "",
text.ccswitch?.cards?.importMap?.title || "",
text.ccswitch?.cards?.manual?.title || "",
]);
replaceAllHtml(
"#ccswitch .grid-2:nth-of-type(1) .card:nth-child(1) .plain-list li",
text.ccswitch?.cards?.download?.items || [],
);
replaceAllText(
"#ccswitch .grid-2:nth-of-type(1) .card:nth-child(1) .meta-row a",
text.ccswitch?.cards?.download?.actions || [],
);
replaceAllHtml(
"#ccswitch .grid-2:nth-of-type(1) .card:nth-child(2) .plain-list li",
text.ccswitch?.cards?.oneClick?.items || [],
);
replaceNodeContent(
"#ccswitch .grid-2:nth-of-type(1) .card:nth-child(2) .note",
text.ccswitch?.cards?.oneClick?.noteHtml || "",
"html",
);
replaceAllText(
"#ccswitch .grid-2:nth-of-type(2) .card:nth-child(1) th",
text.ccswitch?.cards?.importMap?.headers || [],
);
const importRows = document.querySelectorAll(
"#ccswitch .grid-2:nth-of-type(2) .card:nth-child(1) tbody tr",
);
importRows.forEach((row, rowIndex) => {
const cells = row.querySelectorAll("td");
const values = text.ccswitch?.cards?.importMap?.rows?.[rowIndex] || [];
cells.forEach((cell, colIndex) => {
if (values[colIndex] != null) {
cell.innerHTML = values[colIndex];
}
});
});
replaceAllText(
"#ccswitch .grid-2:nth-of-type(2) .card:nth-child(2) label",
text.ccswitch?.cards?.manual?.labels || [],
);
replaceNodeContent(
"#ccswitch .grid-2:nth-of-type(2) .card:nth-child(2) small",
text.ccswitch?.cards?.manual?.hostHelpHtml || "",
"html",
);
replaceAllText(
"#ccswitch .grid-2:nth-of-type(2) .card:nth-child(2) .host-actions button",
text.ccswitch?.cards?.manual?.buttons || [],
);
if (apiKeyInput) {
apiKeyInput.placeholder = text.ccswitch?.cards?.manual?.apiKeyPlaceholder || "";
}
if (platformSelect) {
Array.from(platformSelect.options).forEach((option, index) => {
if (text.ccswitch?.cards?.manual?.options?.[index]) {
option.textContent = text.ccswitch.cards.manual.options[index];
}
});
}
replaceNodeContent("#overview h2", text.overview?.title || "", "text");
replaceNodeContent("#overview .section-desc", text.overview?.descHtml || "", "html");
replaceAllText("#overview th", text.overview?.headers || []);
const overviewRows = document.querySelectorAll("#overview tbody tr");
overviewRows.forEach((row, rowIndex) => {
const cells = row.querySelectorAll("td");
const values = text.overview?.rows?.[rowIndex] || [];
cells.forEach((cell, colIndex) => {
if (values[colIndex] != null) {
cell.innerHTML = values[colIndex];
}
});
});
replaceNodeContent("#hosts h2", text.hosts?.title || "", "text");
replaceNodeContent("#hosts .section-desc", text.hosts?.descHtml || "", "html");
replaceNodeContent("#hosts .note", text.hosts?.noteHtml || "", "html");
replaceNodeContent("#http h2", text.http?.title || "", "text");
replaceNodeContent("#http .section-desc", text.http?.descHtml || "", "html");
replaceNodeContent("#sdk-js h2", text.sdkJs?.title || "", "text");
replaceNodeContent("#sdk-js .section-desc", text.sdkJs?.descHtml || "", "html");
replaceNodeContent("#sdk-python h2", text.sdkPython?.title || "", "text");
replaceNodeContent("#sdk-python .section-desc", text.sdkPython?.descHtml || "", "html");
replaceNodeContent("#claude-code h2", text.claude?.title || "", "text");
replaceNodeContent("#claude-code .section-desc", text.claude?.descHtml || "", "html");
replaceNodeContent("#gemini-cli h2", text.gemini?.title || "", "text");
replaceNodeContent("#gemini-cli .section-desc", text.gemini?.descHtml || "", "html");
replaceNodeContent("#codex-cli h2", text.codex?.title || "", "text");
replaceNodeContent("#codex-cli .section-desc", text.codex?.descHtml || "", "html");
replaceNodeContent("#opencode h2", text.opencode?.title || "", "text");
replaceNodeContent("#opencode .section-desc", text.opencode?.descHtml || "", "html");
replaceNodeContent("#openclaw h2", text.openclaw?.title || "", "text");
replaceNodeContent("#openclaw .section-desc", text.openclaw?.descHtml || "", "html");
replaceNodeContent("#openclaw .note", text.openclaw?.noteHtml || "", "html");
replaceNodeContent("#hermes h2", text.hermes?.title || "", "text");
replaceNodeContent("#hermes .section-desc", text.hermes?.descHtml || "", "html");
replaceNodeContent(
"#hermes .grid-2 .code-block:nth-child(2) .code-title",
text.hermes?.interactiveTitle || "",
"text",
);
replaceNodeContent("#hermes .note", text.hermes?.warningHtml || "", "html");
replaceNodeContent("#faq h2", text.faq?.title || "", "text");
replaceAllText("#faq th", text.faq?.headers || []);
const faqRows = document.querySelectorAll("#faq tbody tr");
faqRows.forEach((row, rowIndex) => {
const cells = row.querySelectorAll("td");
const values = text.faq?.rows?.[rowIndex] || [];
cells.forEach((cell, colIndex) => {
if (values[colIndex] != null) {
cell.innerHTML = values[colIndex];
}
});
});
replaceNodeContent(".footer", text.footerHtml || "", "html");
const copyButtons = document.querySelectorAll(".copy-btn");
copyButtons.forEach((button) => {
button.textContent = text.messages?.copy || "Copy";
});
replaceAllText(".code-title", [
text.codeTitles?.httpChat || "",
text.codeTitles?.httpModels || "",
text.codeTitles?.sdkJs || "",
text.codeTitles?.sdkPython || "",
text.codeTitles?.claude || "",
text.codeTitles?.gemini || "",
text.codeTitles?.codexConfig || "",
text.codeTitles?.codexAuth || "",
text.codeTitles?.opencode || "",
text.codeTitles?.openclaw || "",
text.codeTitles?.hermes || "",
text.codeTitles?.hermesInteractive || "",
]);
const codeHttpChat = document.getElementById("code-http-chat");
const codeHermesInteractive = document.getElementById("code-hermes-interactive");
if (codeHttpChat && text.codeSamples?.httpChat) {
codeHttpChat.textContent = text.codeSamples.httpChat;
}
if (codeHermesInteractive && text.codeSamples?.hermesInteractive) {
codeHermesInteractive.textContent = text.codeSamples.hermesInteractive;
}
defaultHostEls.forEach((el) => {
el.textContent = DEFAULT_HOST;
});
}
function syncState(options) {
const previousLocale = currentLocale;
currentLocale = resolveLocale();
currentTheme = resolveTheme();
if (localeSwitcherEl) {
localeSwitcherEl.value = currentLocale;
}
applyTheme(currentTheme);
renderStaticContent();
updateHeader(publicSettings);
if (options?.reloadHosts || previousLocale !== currentLocale) {
loadPublicSettings();
}
}
async function loadPublicSettings() {
const text = getText();
const builtins = text.hostCard?.builtin || {};
const seeds = [
{
name: builtins.default?.name || "Default primary host",
root: resolveUrl(DEFAULT_HOST),
description: builtins.default?.description || "",
},
];
const currentRoot = resolveUrl(window.location.origin);
if (currentRoot && currentRoot !== resolveUrl(DEFAULT_HOST)) {
seeds.push({
name: builtins.current?.name || "Current site origin",
root: currentRoot,
description: builtins.current?.description || "",
});
}
try {
const response = await fetch("/api/v1/settings/public", {
credentials: "same-origin",
});
const payload = await response.json();
const settings = payload && payload.data ? payload.data : payload;
publicSettings = settings;
updateHeader(settings);
if (
settings &&
typeof settings.site_name === "string" &&
settings.site_name.trim()
) {
providerNameInput.value = settings.site_name.trim();
}
if (settings && settings.api_base_url) {
const apiRoot = resolveUrl(settings.api_base_url);
if (apiRoot) {
seeds.push({
name: builtins.apiBase?.name || "Public API Base URL",
root: apiRoot,
description: builtins.apiBase?.description || "",
});
}
}
if (settings && Array.isArray(settings.custom_endpoints)) {
settings.custom_endpoints.forEach((item, index) => {
const root = resolveUrl(item.endpoint);
if (!root) return;
seeds.push({
name:
item.name ||
`${builtins.customPrefix || "Custom endpoint"} ${index + 1}`,
root: root,
description:
item.description || builtins.customDescription || "",
});
});
}
} catch (error) {
updateHeader(publicSettings);
}
const deduped = uniqueBy(
seeds.filter((item) => item.root),
(item) => item.root,
);
renderHosts(deduped);
}
function initHeaderEvents() {
if (themeToggleEl) {
themeToggleEl.addEventListener("click", () => {
applyTheme(currentTheme === "dark" ? "light" : "dark");
});
}
if (localeSwitcherEl) {
localeSwitcherEl.addEventListener("change", (event) => {
const next = event.target.value === "zh" ? "zh" : "en";
currentLocale = next;
localStorage.setItem(LOCALE_KEY, next);
syncState({ reloadHosts: true });
});
}
}
function initCrossContextSync() {
window.addEventListener("storage", (event) => {
if (
event.key &&
event.key !== LOCALE_KEY &&
event.key !== THEME_KEY &&
event.key !== AUTH_TOKEN_KEY &&
event.key !== AUTH_USER_KEY
) {
return;
}
syncState({
reloadHosts:
event.key === null ||
event.key === LOCALE_KEY ||
event.key === AUTH_TOKEN_KEY ||
event.key === AUTH_USER_KEY,
});
});
}
document.addEventListener("click", (event) => {
const target = event.target;
if (!(target instanceof HTMLElement)) return;
const copyTargetId = target.getAttribute("data-copy-target");
if (copyTargetId) {
const codeEl = document.getElementById(copyTargetId);
if (codeEl) {
copyText(codeEl.textContent || "", target);
}
return;
}
const copyTextValue = target.getAttribute("data-copy-text");
if (copyTextValue) {
copyText(copyTextValue, target);
}
});
if (importBtn) {
importBtn.addEventListener("click", () => {
const text = getText();
try {
const link = buildCcSwitchLink();
resultEl.textContent = text.messages?.tryingOpen || "";
window.open(link, "_self");
setTimeout(() => {
if (document.hasFocus()) {
resultEl.textContent = text.messages?.clientNotOpened || "";
}
}, 120);
} catch (error) {
resultEl.textContent = error.message || text.messages?.importFailed || "";
}
});
}
if (copyLinkBtn) {
copyLinkBtn.addEventListener("click", async () => {
const text = getText();
try {
const link = buildCcSwitchLink();
await copyText(link, copyLinkBtn);
resultEl.textContent = text.messages?.deepLinkCopied || "";
} catch (error) {
resultEl.textContent = error.message || text.messages?.copyFailed || "";
}
});
}
renderStaticContent();
updateHeader(publicSettings);
initHeaderEvents();
initCrossContextSync();
loadPublicSettings();
})();