diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 748932a..8f8d027 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,6 +10,9 @@ importers: reproducibility/site: dependencies: + '@astrojs/sitemap': + specifier: ^3.7.2 + version: 3.7.2 '@astrojs/solid-js': specifier: ^5.0.0 version: 5.1.3(@types/node@20.19.39)(jiti@1.21.7)(solid-js@1.9.12)(tsx@4.21.0)(yaml@2.8.3) diff --git a/reproducibility/site/astro.config.mjs b/reproducibility/site/astro.config.mjs index df3dcb0..3cde561 100644 --- a/reproducibility/site/astro.config.mjs +++ b/reproducibility/site/astro.config.mjs @@ -1,11 +1,33 @@ import { defineConfig } from "astro/config"; import tailwind from "@astrojs/tailwind"; import solid from "@astrojs/solid-js"; +import sitemap from "@astrojs/sitemap"; export default defineConfig({ site: "https://leaderboard.querygym.com", output: "static", - integrations: [tailwind({ applyBaseStyles: false }), solid()], + integrations: [ + tailwind({ applyBaseStyles: false }), + solid(), + sitemap({ + changefreq: "weekly", + priority: 0.5, + lastmod: new Date(), + serialize(item) { + // Home page is the canonical entry point. + if (item.url === "https://leaderboard.querygym.com/") { + return { ...item, priority: 1.0, changefreq: "weekly" }; + } + // Per-run detail pages are mostly internal-link targets — give them + // lower priority so search engines focus on the dataset/method/model + // index pages. + if (item.url.startsWith("https://leaderboard.querygym.com/runs/")) { + return { ...item, priority: 0.3, changefreq: "monthly" }; + } + return item; + }, + }), + ], vite: { ssr: { // Needed because we read CSV/YAML at build time from outside the project root. diff --git a/reproducibility/site/package.json b/reproducibility/site/package.json index e03b79d..2cdfbd8 100644 --- a/reproducibility/site/package.json +++ b/reproducibility/site/package.json @@ -13,22 +13,23 @@ "check": "astro check" }, "dependencies": { - "@qg/shared": "workspace:*", - "astro": "^5.0.0", - "@astrojs/tailwind": "^5.1.5", + "@astrojs/sitemap": "^3.7.2", "@astrojs/solid-js": "^5.0.0", - "solid-js": "^1.9.0", + "@astrojs/tailwind": "^5.1.5", + "@qg/shared": "workspace:*", "@tanstack/solid-table": "^8.20.0", - "tailwindcss": "^3.4.0", + "astro": "^5.0.0", + "js-yaml": "^4.1.0", "papaparse": "^5.4.1", - "js-yaml": "^4.1.0" + "solid-js": "^1.9.0", + "tailwindcss": "^3.4.0" }, "devDependencies": { + "@types/js-yaml": "^4.0.9", + "@types/node": "^20.0.0", + "@types/papaparse": "^5.3.15", "tsx": "^4.19.0", "typescript": "^5.6.0", - "wrangler": "^4.0.0", - "@types/papaparse": "^5.3.15", - "@types/js-yaml": "^4.0.9", - "@types/node": "^20.0.0" + "wrangler": "^4.0.0" } } diff --git a/reproducibility/site/public/robots.txt b/reproducibility/site/public/robots.txt new file mode 100644 index 0000000..c2967cb --- /dev/null +++ b/reproducibility/site/public/robots.txt @@ -0,0 +1,5 @@ +# leaderboard.querygym.com — open to all well-behaved crawlers. +User-agent: * +Allow: / + +Sitemap: https://leaderboard.querygym.com/sitemap-index.xml diff --git a/reproducibility/site/src/components/EmptyState.astro b/reproducibility/site/src/components/EmptyState.astro index aa11ccf..20cfb6f 100644 --- a/reproducibility/site/src/components/EmptyState.astro +++ b/reproducibility/site/src/components/EmptyState.astro @@ -16,8 +16,6 @@ const { How to submit a result → diff --git a/reproducibility/site/src/layouts/Default.astro b/reproducibility/site/src/layouts/Default.astro index 1fac4bd..3a001a9 100644 --- a/reproducibility/site/src/layouts/Default.astro +++ b/reproducibility/site/src/layouts/Default.astro @@ -11,6 +11,7 @@ interface Props { const { title, description } = Astro.props; +// External links render the linkout icon and open in the current tab. const navLinks = [ { label: "Datasets", href: "/datasets/" }, { label: "Methods", href: "/methods/" }, @@ -28,6 +29,7 @@ const navLinks = [ {title} — QueryGym Leaderboard {description && } + diff --git a/web/shared/components/Footer.astro b/web/shared/components/Footer.astro index a65896d..19518d7 100644 --- a/web/shared/components/Footer.astro +++ b/web/shared/components/Footer.astro @@ -35,7 +35,7 @@ const baseLinks: FooterLink[] = [ { [...baseLinks, ...extraLinks].map((l) => (
  • - + {l.label}
  • diff --git a/web/shared/components/Header.astro b/web/shared/components/Header.astro index 84526c1..ab41dc9 100644 --- a/web/shared/components/Header.astro +++ b/web/shared/components/Header.astro @@ -7,7 +7,15 @@ interface NavLink { label: string; href: string; + /** + * Renders the external-link arrow icon next to the label so users can see + * at a glance that the link leaves the current site. Note: by default the + * link still opens in the *same* tab — set `newTab: true` for cross-site + * links you really want to open in a fresh tab. + */ external?: boolean; + /** Open in a new tab. Adds rel="noopener noreferrer" automatically. */ + newTab?: boolean; } interface Props { @@ -44,11 +52,28 @@ const { links.map((l) => ( {l.label} + {l.external && ( + + )} )) } diff --git a/web/site/src/components/EcosystemMap.astro b/web/site/src/components/EcosystemMap.astro index 270ff0c..5bb74f9 100644 --- a/web/site/src/components/EcosystemMap.astro +++ b/web/site/src/components/EcosystemMap.astro @@ -53,8 +53,6 @@ const cards = [ cards.map((c) => ( - + {jsonLd &&