-
Notifications
You must be signed in to change notification settings - Fork 1
chore(docs): sitemap #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,6 @@ | ||
| User-agent: * | ||
| Disallow: | ||
| Allow: / | ||
| Disallow: /assets/ | ||
| Disallow: /.pagefind/ | ||
|
|
||
| Sitemap: https://nvidia.github.io/elements/sitemap.xml |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,29 +1,32 @@ | ||
| /* eslint-env node */ | ||
| /* global process */ | ||
|
|
||
| import { join } from 'node:path'; | ||
| import { ELEMENTS_PAGES_BASE_URL, ELEMENTS_PLAYGROUND_BASE_URL, ELEMENTS_REPO_BASE_URL } from '../utils/env.js'; | ||
|
|
||
| export const BASE_URL = join('/', process.env.PAGES_BASE_URL ?? '', '/'); | ||
| import { ELEMENTS_PLAYGROUND_BASE_URL, ELEMENTS_REPO_BASE_URL } from '../utils/env.js'; | ||
| import { escapeAttr, resolvePageMeta, renderJsonLd, BASE_URL } from './metadata.js'; | ||
|
|
||
| /** | ||
| * This renders the base head element with all the common styles and scripts needed for ALL PAGES. | ||
| * Page specific resources should not be placed here. | ||
| */ | ||
| export const renderBaseHead = data => /* html */ ` | ||
| export const renderBaseHead = data => { | ||
| const meta = resolvePageMeta(data); | ||
| const ogType = meta.url === '/' ? 'website' : 'article'; | ||
| return /* html */ ` | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <meta name="robots" content="all"> | ||
| <base href="${BASE_URL}" /> | ||
| <title data-pagefind-meta="title">${data.title}</title> | ||
| <meta name="description" content="Elements - ${data.title}"> | ||
| <meta property="og:title" content="Elements - ${data.title}" > | ||
| <meta property="og:url" content="${data.page?.url ?? ''}"> | ||
| <meta property="og:description" content="NVIDIA Elements is a flexible, framework-agnostic design system and toolkit that empowers teams to build exceptional user experiences."> | ||
| <meta property="og:image" content="/favicon.svg"> | ||
| <meta property="og:site_name" content="${ELEMENTS_PAGES_BASE_URL}/"> | ||
| <meta property="og:type" content="website"> | ||
| <title data-pagefind-meta="title">${escapeAttr(meta.title)}</title> | ||
| <meta name="description" content="${escapeAttr(meta.description)}"> | ||
| <link rel="canonical" href="${meta.canonicalUrl}"> | ||
| <meta property="og:title" content="${escapeAttr(meta.title)}"> | ||
| <meta property="og:url" content="${meta.canonicalUrl}"> | ||
| <meta property="og:description" content="${escapeAttr(meta.description)}"> | ||
| <meta property="og:image" content="${meta.ogImage}"> | ||
|
Comment on lines
+21
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Escape Line 21, Line 23, and Line 25 interpolate raw values into Proposed hardening- <link rel="canonical" href="${meta.canonicalUrl}">
+ <link rel="canonical" href="${escapeAttr(meta.canonicalUrl)}">
<meta property="og:title" content="${escapeAttr(meta.title)}">
- <meta property="og:url" content="${meta.canonicalUrl}">
+ <meta property="og:url" content="${escapeAttr(meta.canonicalUrl)}">
<meta property="og:description" content="${escapeAttr(meta.description)}">
- <meta property="og:image" content="${meta.ogImage}">
+ <meta property="og:image" content="${escapeAttr(meta.ogImage)}">🤖 Prompt for AI Agents |
||
| <meta property="og:site_name" content="NVIDIA Elements"> | ||
| <meta property="og:type" content="${ogType}"> | ||
| <link rel="icon" href="/favicon.svg"> | ||
| ${renderJsonLd(data, meta)} | ||
| ${renderGlobalsScript(data)} | ||
| <style> | ||
| @import '@nvidia-elements/themes/fonts/inter.css'; | ||
|
|
@@ -99,6 +102,7 @@ export const renderBaseHead = data => /* html */ ` | |
| globalThis.document.documentElement.removeAttribute('no-js'); | ||
| </script> | ||
| `; | ||
| }; | ||
|
|
||
| export const renderDocsNav = data => /* html */ ` | ||
| <nve-tree id="docs-nav" data-pagefind-ignore="all" behavior-expand selectable="single"> | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,133 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { join } from 'node:path'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
coryrylan marked this conversation as resolved.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { ELEMENTS_SITE_URL } from '../utils/env.js'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { siteData } from '../../index.11tydata.js'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const BASE_URL = join('/', process.env.PAGES_BASE_URL ?? '', '/'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| const SITE_ORIGIN = ELEMENTS_SITE_URL.replace(/\/$/, ''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| const PATH_PREFIX = BASE_URL.replace(/\/$/, ''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| const BREADCRUMB_TERMS = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| api: 'API', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| cli: 'CLI', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| mcp: 'MCP', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ssr: 'SSR', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| i18n: 'i18n', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ui: 'UI', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| nextjs: 'Next.js', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| solidjs: 'SolidJS', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| nuxt: 'Nuxt', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| typescript: 'TypeScript', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| go: 'Go', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| vue: 'Vue', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| react: 'React', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| svelte: 'Svelte', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| preact: 'Preact', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| lit: 'Lit', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| hugo: 'Hugo', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| angular: 'Angular', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| monaco: 'Monaco', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| jsdoc: 'JSDoc', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| json: 'JSON', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| html: 'HTML', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| css: 'CSS', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| nvidia: 'NVIDIA', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| npm: 'npm' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| export function escapeAttr(value) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return String(value ?? '') | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| .replace(/&/g, '&') | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| .replace(/</g, '<') | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| .replace(/>/g, '>') | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| .replace(/"/g, '"') | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| .replace(/'/g, '''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+38
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Add JSDoc contracts for metadata helpers and decision branches. Please document expected inputs/outputs and constraints for As per coding guidelines, "Document agent capabilities, constraints, and expected inputs/outputs in code comments or docstrings" and "Use structured logging to track agent decision-making processes and state changes for debugging and monitoring". Also applies to: 60-83, 89-133 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| function titleCaseSegment(segment) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (BREADCRUMB_TERMS[segment]) return BREADCRUMB_TERMS[segment]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return segment | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| .split('-') | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| .map(part => BREADCRUMB_TERMS[part] ?? part.charAt(0).toUpperCase() + part.slice(1)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| .join(' '); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| function findElementByTag(tag) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!tag) return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return siteData.elements.find(e => e.name === tag) ?? null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| export function resolvePageMeta(data) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| const url = data.page?.url ?? '/'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| const title = data.title ?? 'NVIDIA Elements'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| const tag = data.tag ?? data.component?.data?.tag; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| const element = findElementByTag(tag); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| const componentDescription = element?.manifest?.description?.trim(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| let description; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (data.description) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| description = data.description; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if (data.isApiTab && componentDescription) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| description = `${componentDescription} — API reference for <${tag}>.`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if (data.isExamplesTab && componentDescription) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| description = `${componentDescription} — Interactive examples for <${tag}>.`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if (componentDescription) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| description = componentDescription; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| description = `Documentation for ${title} in NVIDIA Elements, the framework-agnostic design system for AI/ML factories.`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| const canonicalUrl = `${SITE_ORIGIN}${PATH_PREFIX}${url}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| const ogImage = `${SITE_ORIGIN}${PATH_PREFIX}/favicon.svg`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { title, description, canonicalUrl, ogImage, url }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| function jsonLdEncode(value) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return JSON.stringify(value).replace(/<\//g, '<\\/'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| export function renderJsonLd(data, meta) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| const isDocs = meta.url.startsWith('/docs/'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| const articleType = isDocs ? 'TechArticle' : 'WebPage'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| const date = data.page?.date instanceof Date ? data.page.date.toISOString() : new Date().toISOString(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| const article = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| '@context': 'https://schema.org', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| '@type': articleType, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| headline: meta.title, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: meta.description, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| url: meta.canonicalUrl, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| mainEntityOfPage: meta.canonicalUrl, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| inLanguage: 'en', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| image: meta.ogImage, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| datePublished: date, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| dateModified: date, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+92
to
+104
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid build-time “now” as JSON-LD publish/modify dates. Line 92 falls back to Suggested fix- const date = data.page?.date instanceof Date ? data.page.date.toISOString() : new Date().toISOString();
+ const date = data.page?.date instanceof Date ? data.page.date.toISOString() : null;
@@
- datePublished: date,
- dateModified: date,
+ ...(date ? { datePublished: date, dateModified: date } : {}),📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| publisher: { '@type': 'Organization', name: 'NVIDIA', url: SITE_ORIGIN }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| author: { '@type': 'Organization', name: 'NVIDIA' } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| const segments = meta.url.split('/').filter(Boolean); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| const articleScript = `<script type="application/ld+json">${jsonLdEncode(article)}</script>`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (segments.length === 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return articleScript; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| const itemListElement = [{ '@type': 'ListItem', position: 1, name: 'Home', item: `${SITE_ORIGIN}${PATH_PREFIX}/` }]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| let cumulative = ''; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| segments.forEach((seg, i) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| cumulative += `/${seg}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| itemListElement.push({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| '@type': 'ListItem', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| position: i + 2, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: titleCaseSegment(seg), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| item: `${SITE_ORIGIN}${PATH_PREFIX}${cumulative}/` | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| const breadcrumb = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| '@context': 'https://schema.org', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| '@type': 'BreadcrumbList', | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| itemListElement | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return `${articleScript}\n <script type="application/ld+json">${jsonLdEncode(breadcrumb)}</script>`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,36 @@ | ||||||||||||||
| import { promises as fsp } from 'node:fs'; | ||||||||||||||
| import { BASE_URL } from '../layouts/metadata.js'; | ||||||||||||||
| import { ELEMENTS_SITE_URL } from '../utils/env.js'; | ||||||||||||||
|
|
||||||||||||||
| const SITE_ORIGIN = ELEMENTS_SITE_URL.replace(/\/$/, ''); | ||||||||||||||
| const PATH_PREFIX = BASE_URL.replace(/\/$/, ''); | ||||||||||||||
| const EXCLUDED_PREFIXES = ['/docs/changelog/', '/docs/metrics/', '/examples/', '/404']; | ||||||||||||||
|
|
||||||||||||||
| function isPublishable(url) { | ||||||||||||||
| if (!url) return false; | ||||||||||||||
| if (!url.endsWith('/') && !url.endsWith('.html')) return false; | ||||||||||||||
| if (EXCLUDED_PREFIXES.some(prefix => url.startsWith(prefix))) return false; | ||||||||||||||
| return true; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| export function sitemapPlugin(eleventyConfig) { | ||||||||||||||
| eleventyConfig.on('eleventy.after', async ({ results } = {}) => { | ||||||||||||||
| const urls = [...new Set((results ?? []).map(r => r.url).filter(isPublishable))].sort(); | ||||||||||||||
| const lastmod = new Date().toISOString(); | ||||||||||||||
| const entries = urls.map(url => { | ||||||||||||||
| const loc = `${SITE_ORIGIN}${PATH_PREFIX}${url}`; | ||||||||||||||
| return ['<url>', `<loc>${loc}</loc>`, `<lastmod>${lastmod}</lastmod>`, '</url>'].join('\n'); | ||||||||||||||
| }); | ||||||||||||||
|
Comment on lines
+21
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Escape Line 22 writes raw URL text into XML. If a URL contains XML-sensitive characters, sitemap output becomes invalid. Proposed hardening+const escapeXml = value =>
+ value
+ .replaceAll('&', '&')
+ .replaceAll('<', '<')
+ .replaceAll('>', '>')
+ .replaceAll('"', '"')
+ .replaceAll("'", ''');
+
export function sitemapPlugin(eleventyConfig) {
eleventyConfig.on('eleventy.after', async ({ results } = {}) => {
@@
const entries = urls.map(url => {
const loc = `${SITE_ORIGIN}${PATH_PREFIX}${url}`;
- return ['<url>', `<loc>${loc}</loc>`, `<lastmod>${lastmod}</lastmod>`, '</url>'].join('\n');
+ return ['<url>', `<loc>${escapeXml(loc)}</loc>`, `<lastmod>${lastmod}</lastmod>`, '</url>'].join('\n');
});📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| const xml = [ | ||||||||||||||
| '<?xml version="1.0" encoding="UTF-8"?>', | ||||||||||||||
| '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">', | ||||||||||||||
| ...entries, | ||||||||||||||
| '</urlset>', | ||||||||||||||
| '' | ||||||||||||||
| ].join('\n'); | ||||||||||||||
|
|
||||||||||||||
| await fsp.mkdir('./.11ty-vite/public/', { recursive: true }); | ||||||||||||||
| await fsp.writeFile('./.11ty-vite/public/sitemap.xml', xml, 'utf-8'); | ||||||||||||||
| }); | ||||||||||||||
| } | ||||||||||||||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Document
ELEMENTS_SITE_URLin build docs.ELEMENTS_SITE_URLwas added to build-time Wireit env; please ensure/projects/internals/BUILD.mddocuments this variable and default value so CI/CD and local build docs stay aligned.Based on learnings: "Review /projects/internals/BUILD.md when modifying build configuration, Wireit scripts, or CI/CD pipeline".
🤖 Prompt for AI Agents