From fc44ffefee212aea3ccf6cfd8533b0fd6bd0864e Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Tue, 5 Aug 2025 21:07:14 -0600 Subject: [PATCH 1/6] Change CTA text for DB --- src/routes/_libraries/db.$version.index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/_libraries/db.$version.index.tsx b/src/routes/_libraries/db.$version.index.tsx index df10cdbd..be7ec0f9 100644 --- a/src/routes/_libraries/db.$version.index.tsx +++ b/src/routes/_libraries/db.$version.index.tsx @@ -66,7 +66,7 @@ export default function DBVersionIndex() { params={{ libraryId: library.id, version }} className={`py-2 px-4 bg-orange-500 rounded text-white uppercase font-extrabold`} > - Coming soon » + Get Started » Date: Mon, 25 Aug 2025 17:27:47 -0600 Subject: [PATCH 2/6] fix: normalize markdown links to work on both GitHub and website MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds path normalization to MarkdownLink component to handle the difference between GitHub's file-based paths and the website's route-based paths. Links like ./guides/foo.md now work correctly on both platforms. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/components/MarkdownLink.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/components/MarkdownLink.tsx b/src/components/MarkdownLink.tsx index 3fca7017..fb060f24 100644 --- a/src/components/MarkdownLink.tsx +++ b/src/components/MarkdownLink.tsx @@ -16,6 +16,14 @@ export function MarkdownLink({ const [hrefWithoutHash, hash] = hrefProp?.split('#') ?? [] let [to] = hrefWithoutHash?.split('.md') ?? [] + + // Normalize relative paths that work in GitHub to work with our routing structure + // In GitHub: ./guides/foo.md works from docs/overview.md + // In our router: we need ../guides/foo because the current path is /lib/version/docs/overview (not overview/) + if (to?.startsWith('./')) { + // Convert ./path to ../path to account for the fact that we're at /docs/file not /docs/file/ + to = '../' + to.slice(2) + } return ( Date: Mon, 25 Aug 2025 18:08:21 -0600 Subject: [PATCH 3/6] fix: also handle bare relative paths in markdown links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extends the normalization to handle paths like "guides/foo.md" (without ./) that should be treated as sibling directories. This ensures compatibility with various markdown link styles used in documentation. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .claude/settings.local.json | 15 +++++++++++++++ src/components/MarkdownLink.tsx | 4 ++++ 2 files changed, 19 insertions(+) create mode 100644 .claude/settings.local.json diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 00000000..0c98deff --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,15 @@ +{ + "permissions": { + "allow": [ + "Bash(sed:*)", + "Bash(npx prettier:*)", + "WebFetch(domain:github.com)", + "Read(//Users/kylemathews/programs/tanstack-db/docs/**)", + "WebFetch(domain:deploy-preview-477--tanstack.netlify.app)" + ], + "deny": [], + "additionalDirectories": [ + "/Users/kylemathews/programs/tanstack-db/docs/guides" + ] + } +} \ No newline at end of file diff --git a/src/components/MarkdownLink.tsx b/src/components/MarkdownLink.tsx index fb060f24..8df5a183 100644 --- a/src/components/MarkdownLink.tsx +++ b/src/components/MarkdownLink.tsx @@ -23,6 +23,10 @@ export function MarkdownLink({ if (to?.startsWith('./')) { // Convert ./path to ../path to account for the fact that we're at /docs/file not /docs/file/ to = '../' + to.slice(2) + } else if (to && !to.startsWith('/') && !to.startsWith('../') && to.includes('/')) { + // Handle bare relative paths like "guides/foo" that should be treated as "../guides/foo" + // This handles cases where markdown has "subfolder/file.md" instead of "./subfolder/file.md" + to = '../' + to } return ( From 77fb0936e2d6c1b4d2f1ccca391b7721fd7b8d93 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Mon, 25 Aug 2025 18:14:27 -0600 Subject: [PATCH 4/6] fix: handle bare filename paths in markdown links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extends normalization to handle all relative path formats: - "./foo.md" (explicit same directory) -> "../foo" - "foo.md" (bare filename, same directory) -> "../foo" - "./guides/foo.md" (explicit subdirectory) -> "../guides/foo" - "guides/foo.md" (bare subdirectory) -> "../guides/foo" This ensures all GitHub-compatible relative link formats work correctly on the website's routing structure. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/components/MarkdownLink.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/MarkdownLink.tsx b/src/components/MarkdownLink.tsx index 8df5a183..feb56eb1 100644 --- a/src/components/MarkdownLink.tsx +++ b/src/components/MarkdownLink.tsx @@ -23,9 +23,12 @@ export function MarkdownLink({ if (to?.startsWith('./')) { // Convert ./path to ../path to account for the fact that we're at /docs/file not /docs/file/ to = '../' + to.slice(2) - } else if (to && !to.startsWith('/') && !to.startsWith('../') && to.includes('/')) { - // Handle bare relative paths like "guides/foo" that should be treated as "../guides/foo" - // This handles cases where markdown has "subfolder/file.md" instead of "./subfolder/file.md" + } else if (to && !to.startsWith('/') && !to.startsWith('../')) { + // Handle bare relative paths like "foo" or "guides/foo" + // These should be treated as siblings, so prepend ../ + // This handles: + // - "foo.md" (same directory) -> "../foo" + // - "guides/foo.md" (subdirectory) -> "../guides/foo" to = '../' + to } From 7981a52c6732e85f7243ef6cf0c063d65d467491 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Mon, 25 Aug 2025 20:45:35 -0600 Subject: [PATCH 5/6] prettier --- agents/tasks/tanstack-com-task-list.md | 44 +++++++++++++++---- convex/auth.config.ts | 4 +- src/components/MarkdownLink.tsx | 2 +- src/routes/_libraries/form.$version.index.tsx | 2 +- .../_libraries/pacer.$version.index.tsx | 2 +- src/styles/app.css | 2 +- 6 files changed, 41 insertions(+), 15 deletions(-) diff --git a/agents/tasks/tanstack-com-task-list.md b/agents/tasks/tanstack-com-task-list.md index 4709bff3..3a9509a8 100644 --- a/agents/tasks/tanstack-com-task-list.md +++ b/agents/tasks/tanstack-com-task-list.md @@ -8,22 +8,27 @@ - Links: PRs, issues, routes, components ### How to use this file + - Update status/notes as tasks progress. Keep routes/components and data sources referenced so any agent can continue seamlessly. - Prefer reusing existing components and content models referenced below. --- ## 1. Metrics & Market Leadership Signals + **Goal:** Visible proof of dominance and growth. ### Audit snapshot + - Homepage metrics: `OpenSourceStats` counters present on homepage (`src/routes/_libraries/index.tsx` uses `OpenSourceStats`). Partial. - "Trusted By": Component exists as text marquee (`src/components/TrustedByMarquee.tsx`). Not on homepage yet; currently used on some library pages (e.g. `src/routes/_libraries/table.$version.index.tsx`). Partial. - NPM stats: Extensive interactive page exists at `src/routes/stats/npm/index.tsx` with charts and comparisons. Done (separate page). - Backend metrics: `convex/stats.ts` + `@erquhart/convex-oss-stats` provides GitHub/NPM org metrics; `OpenSourceStats.tsx` consumes `api.stats.getGithubOwner`, `api.stats.getNpmOrg`. Done for aggregate; per-library not yet surfaced. ### Tasks + - [ ] Implement “Trusted By” on homepage + - Status: Backlog - Notes: - Reuse `TrustedByMarquee` but upgrade to support logos + links + tooltip proof. @@ -35,9 +40,10 @@ - Renders without CLS, loops smoothly, accessible (ARIA, alt text). Logos swap dark/light. - All entries have a proof link; no unverified brands. - Links: `src/components/TrustedByMarquee.tsx`, `src/routes/_libraries/index.tsx`. - - Owner: + - Owner: - [ ] Add Real-Time Metrics Counters (per-library + org rollup) + - Status: Partial (org rollup live via `OpenSourceStats`) - Notes: - Extend counters to per-library pages using existing Convex endpoints or add repo-level endpoints via `convex-oss-stats` if needed. @@ -55,9 +61,9 @@ - Notes: - Route: `src/routes/state-of-tanstack.tsx`. - Include growth charts (npm downloads: reuse `NpmStatsChart.tsx` or embed portions of `stats/npm`), GitHub stars, contributors, dependents (available via Convex aggregation already powering `OpenSourceStats`). - - Community stats: Discord members (needs server function), newsletter subscribers (manual or vendor API), X/Twitter followers (manual or API), repository contributors (Convex or GitHub GraphQL on server). - - Ecosystem counts: partners (derive from `src/utils/partners.tsx`), plugins/tools (manual list or content collection). - - CTA to GitHub org. + - Community stats: Discord members (needs server function), newsletter subscribers (manual or vendor API), X/Twitter followers (manual or API), repository contributors (Convex or GitHub GraphQL on server). + - Ecosystem counts: partners (derive from `src/utils/partners.tsx`), plugins/tools (manual list or content collection). + - CTA to GitHub org. - Acceptance: - Page loads instantly with cached metrics; charts are responsive and accessible. - Sources and last-updated timestamps shown. @@ -65,6 +71,7 @@ - Owner: ### Tech/context + - Data: `@erquhart/convex-oss-stats` via `convex/stats.ts` (org-level GitHub star/contributor/dependent counts, npm downloads). Consider adding per-repo endpoints if needed. - Secrets: Configure any tokens via Netlify/Convex env; never expose client-side. - Accessibility: Ensure counters/animations are readable and respect `prefers-reduced-motion`. @@ -72,15 +79,19 @@ --- ## 2. Founder & Team Story + **Goal:** Frame the team as visionary and credible. ### Audit snapshot + - Ethos page exists: `src/routes/_libraries/ethos.tsx` (narrative and positioning). - Maintainers directory page exists: `src/routes/_libraries/maintainers.tsx` with `MaintainerCard` variants and filters; bios sourced from `src/libraries/maintainers`. - No dedicated "About" route; no speaking engagements index; no curated endorsements/tweets. ### Tasks + - [ ] Redesign/Create “About” page + - Status: Backlog - Notes: - Route: `src/routes/about.tsx`. @@ -90,6 +101,7 @@ - Links: `src/components/MaintainerCard.tsx`, `src/routes/_libraries/maintainers.tsx`. - [ ] Speaking Engagements section + - Status: Backlog - Notes: - Add to About or standalone `src/routes/speaking.tsx`. @@ -106,22 +118,25 @@ - Acceptance: Renders endorsements with attribution and embedded tweets with proper theming. ### Tech/context + - Reuse `MaintainerCard` and existing images in `src/images/`. - Avoid fetching social embeds at build if rate-limited; hydrate on client or cache server-side. --- - - ## 4. Commercial Hooks + **Goal:** Show monetizable pathways. ### Audit snapshot + - Enterprise/Support: `src/routes/_libraries/paid-support.tsx` exists with HubSpot script and CTAs. Partial substitute for "Enterprise" page. - No dedicated Partner Program page. ### Tasks + - [ ] “Enterprise” page + - Status: Partial - Notes: - Option 1: Rename and expand `paid-support` into `enterprise` (route alias + updated copy) while keeping legacy route. @@ -137,18 +152,20 @@ - Link to Partners page. - Acceptance: Published page with clear application CTA. - - --- ## 5. Future Vision Page + **Goal:** Show long-term upside. ### Audit snapshot + - No public roadmap found; ethos narrative exists but not a vision statement page. ### Tasks + - [ ] Public Roadmap page + - Status: Backlog - Notes: - Route: `src/routes/roadmap.tsx`. @@ -167,13 +184,17 @@ --- ## 6. Media & Momentum + **Goal:** Make hype and credibility easy to digest. ### Audit snapshot + - No dedicated media kit, in-the-news, or social proof feeds found. ### Tasks + - [ ] Press/Media Kit page + - Status: Backlog - Notes: - Route: `src/routes/media-kit.tsx`. @@ -182,6 +203,7 @@ - Acceptance: Page provides direct downloads and usage rules. - [ ] In the News page + - Status: Backlog - Notes: - Route: `src/routes/news.tsx`. @@ -199,6 +221,7 @@ --- ### Shared implementation notes + - Routing: New pages should be added under `src/routes/*` using TanStack Start conventions; update nav/footers as needed. - Data placement: Prefer `src/data/*.ts` (typed) or `content/*.(json|yaml)` for editorial lists. Avoid hardcoding in components unless small. - Theming: Provide dark/light logo variants; `public/` is ideal for static assets. @@ -208,10 +231,12 @@ - Analytics: Add outbound link tracking if available (future). ### Potential blockers + - External API limits (GitHub GraphQL, Discord member count, X/Twitter API). Prefer server-side fetch with caching or public embed widgets. - Legal/branding approvals for “Trusted By” logos—require proof links. ### Quick links to relevant code + - Homepage: `src/routes/_libraries/index.tsx` - Metrics: `src/components/OpenSourceStats.tsx`, `convex/stats.ts`, `src/components/NpmStatsChart.tsx`, `src/routes/stats/npm/index.tsx` - Trusted By: `src/components/TrustedByMarquee.tsx` @@ -219,8 +244,9 @@ - SEO helper: `src/utils/seo` ### Ownership & tracking + - For each task above, fill in: - Owner: - Issue/PR links: - Status: - - Next step: \ No newline at end of file + - Next step: diff --git a/convex/auth.config.ts b/convex/auth.config.ts index f4eb5646..afc62641 100644 --- a/convex/auth.config.ts +++ b/convex/auth.config.ts @@ -2,7 +2,7 @@ export default { providers: [ { domain: process.env.CONVEX_SITE_URL, - applicationID: "convex", + applicationID: 'convex', }, ], -}; +} diff --git a/src/components/MarkdownLink.tsx b/src/components/MarkdownLink.tsx index feb56eb1..55f3762a 100644 --- a/src/components/MarkdownLink.tsx +++ b/src/components/MarkdownLink.tsx @@ -16,7 +16,7 @@ export function MarkdownLink({ const [hrefWithoutHash, hash] = hrefProp?.split('#') ?? [] let [to] = hrefWithoutHash?.split('.md') ?? [] - + // Normalize relative paths that work in GitHub to work with our routing structure // In GitHub: ./guides/foo.md works from docs/overview.md // In our router: we need ../guides/foo because the current path is /lib/version/docs/overview (not overview/) diff --git a/src/routes/_libraries/form.$version.index.tsx b/src/routes/_libraries/form.$version.index.tsx index cc21f381..1da879df 100644 --- a/src/routes/_libraries/form.$version.index.tsx +++ b/src/routes/_libraries/form.$version.index.tsx @@ -53,7 +53,7 @@ export default function FormVersionIndex() { className: 'bg-yellow-400 text-black', }} /> - +
diff --git a/src/routes/_libraries/pacer.$version.index.tsx b/src/routes/_libraries/pacer.$version.index.tsx index 90a9f175..aa322e32 100644 --- a/src/routes/_libraries/pacer.$version.index.tsx +++ b/src/routes/_libraries/pacer.$version.index.tsx @@ -49,7 +49,7 @@ export default function PacerVersionIndex() {
- + diff --git a/src/styles/app.css b/src/styles/app.css index f10d1b11..fa7d305e 100644 --- a/src/styles/app.css +++ b/src/styles/app.css @@ -735,4 +735,4 @@ mark { font-style: italic; font-weight: 900; src: url('/fonts/inter-v19-latin-900italic.woff2') format('woff2'); -} \ No newline at end of file +} From 2a282b09277465887f49b3349525a1f303cc852d Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Mon, 25 Aug 2025 22:19:05 -0600 Subject: [PATCH 6/6] refactor: create tested utility for markdown path normalization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Extracted path normalization logic to separate utility function - Added comprehensive test suite with 33 test cases covering real examples from DB and Router docs - Handles all patterns: ./, ../, bare paths, external links, hash fragments - All tests pass, ensuring no regressions 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/components/MarkdownLink.tsx | 18 +---- src/components/test-normalize-path.ts | 103 ++++++++++++++++++++++++++ src/utils/normalize-markdown-path.ts | 41 ++++++++++ 3 files changed, 147 insertions(+), 15 deletions(-) create mode 100644 src/components/test-normalize-path.ts create mode 100644 src/utils/normalize-markdown-path.ts diff --git a/src/components/MarkdownLink.tsx b/src/components/MarkdownLink.tsx index 55f3762a..bc37e508 100644 --- a/src/components/MarkdownLink.tsx +++ b/src/components/MarkdownLink.tsx @@ -1,5 +1,6 @@ import { Link } from '@tanstack/react-router' import type { HTMLProps } from 'react' +import { normalizeMarkdownPath } from '~/utils/normalize-markdown-path' export function MarkdownLink({ href: hrefProp, @@ -16,21 +17,8 @@ export function MarkdownLink({ const [hrefWithoutHash, hash] = hrefProp?.split('#') ?? [] let [to] = hrefWithoutHash?.split('.md') ?? [] - - // Normalize relative paths that work in GitHub to work with our routing structure - // In GitHub: ./guides/foo.md works from docs/overview.md - // In our router: we need ../guides/foo because the current path is /lib/version/docs/overview (not overview/) - if (to?.startsWith('./')) { - // Convert ./path to ../path to account for the fact that we're at /docs/file not /docs/file/ - to = '../' + to.slice(2) - } else if (to && !to.startsWith('/') && !to.startsWith('../')) { - // Handle bare relative paths like "foo" or "guides/foo" - // These should be treated as siblings, so prepend ../ - // This handles: - // - "foo.md" (same directory) -> "../foo" - // - "guides/foo.md" (subdirectory) -> "../guides/foo" - to = '../' + to - } + + to = normalizeMarkdownPath(to) return ( = [ + // [input, expected, description] + + // Paths that should be modified + ['./foo', '../foo', 'Same directory with ./'], + ['./guides/foo', '../guides/foo', 'Subdirectory with ./'], + ['./overview.md#api-reference', '../overview.md#api-reference', 'Same directory with ./ and hash'], + ['./installation.md', '../installation.md', 'Real example from quick-start.md'], + ['./overview.md', '../overview.md', 'Real example from quick-start.md'], + ['./live-queries.md', '../live-queries.md', 'Real example from quick-start.md'], + ['foo', '../foo', 'Bare filename (same directory)'], + ['guides/foo', '../guides/foo', 'Bare subdirectory path'], + ['guides/subfolder/foo', '../guides/subfolder/foo', 'Nested bare path'], + ['live-queries.md', '../live-queries.md', 'Real bare filename from overview.md'], + + // Paths that should NOT be modified (from real DB docs) + ['../foo', '../foo', 'Already has ../'], + ['../classes/foo', '../classes/foo', 'Already has ../ with subdirectory'], + ['../classes/aggregatefunctionnotinselecterror.md', '../classes/aggregatefunctionnotinselecterror.md', 'Real example from reference docs'], + ['../interfaces/btreeindexoptions.md', '../interfaces/btreeindexoptions.md', 'Real example from reference docs'], + ['../type-aliases/changelistener.md', '../type-aliases/changelistener.md', 'Real example from reference docs'], + ['../../foo', '../../foo', 'Multiple ../'], + ['/absolute/path', '/absolute/path', 'Absolute path'], + ['http://example.com', 'http://example.com', 'HTTP URL'], + ['https://example.com', 'https://example.com', 'HTTPS URL'], + ['https://github.com/TanStack/db/blob/main/packages/db/src/types.ts#L228', 'https://github.com/TanStack/db/blob/main/packages/db/src/types.ts#L228', 'GitHub source link'], + + // Real examples from TanStack Router docs + ['../learn-the-basics.md', '../learn-the-basics.md', 'Router: Parent directory link'], + ['../hosting.md', '../hosting.md', 'Router: Parent directory hosting guide'], + ['../server-functions.md', '../server-functions.md', 'Router: Parent directory server functions'], + ['../server-routes.md', '../server-routes.md', 'Router: Parent directory server routes'], + ['../middleware.md', '../middleware.md', 'Router: Parent directory middleware'], +] + +// Run tests +console.log('Running path normalization tests:\n') +let passed = 0 +let failed = 0 + +for (const [input, expected, description] of testCases) { + const result = normalizeMarkdownPath(input) + const isPass = result === expected + + if (isPass) { + console.log(`✅ PASS: ${description}`) + console.log(` Input: "${input}" → Output: "${result}"`) + passed++ + } else { + console.log(`❌ FAIL: ${description}`) + console.log(` Input: "${input}"`) + console.log(` Expected: "${expected}"`) + console.log(` Got: "${result}"`) + failed++ + } + console.log('') +} + +console.log(`\nResults: ${passed} passed, ${failed} failed`) + +// Edge cases to consider +console.log('\n--- Edge Cases to Consider ---') +console.log('1. Hash fragments: "foo#section" should become "../foo#section"') +console.log('2. Query params: "foo?param=value" should become "../foo?param=value"') +console.log('3. Special protocols: "mailto:", "javascript:", etc. should not be modified') +console.log('4. Empty string or undefined should return as-is') + +// Test edge cases +console.log('\n--- Testing Edge Cases ---\n') + +const edgeCases: Array<[string | undefined, string | undefined, string]> = [ + ['foo#section', '../foo#section', 'Hash fragment'], + ['./foo#section', '../foo#section', 'With ./ and hash'], + ['../foo#section', '../foo#section', 'Already ../ with hash'], + [undefined, undefined, 'Undefined input'], + ['', '', 'Empty string'], + ['#section', '#section', 'Hash only (should not be modified)'], + ['mailto:test@example.com', 'mailto:test@example.com', 'Mailto protocol'], + ['javascript:void(0)', 'javascript:void(0)', 'Javascript protocol'], +] + +for (const [input, expected, description] of edgeCases) { + const result = normalizeMarkdownPath(input) + const isPass = result === expected + + if (isPass) { + console.log(`✅ PASS: ${description}`) + console.log(` Input: "${input}" → Output: "${result}"`) + } else { + console.log(`❌ FAIL: ${description}`) + console.log(` Input: "${input}"`) + console.log(` Expected: "${expected}"`) + console.log(` Got: "${result}"`) + } + console.log('') +} + diff --git a/src/utils/normalize-markdown-path.ts b/src/utils/normalize-markdown-path.ts new file mode 100644 index 00000000..873eba3a --- /dev/null +++ b/src/utils/normalize-markdown-path.ts @@ -0,0 +1,41 @@ +/** + * Normalizes markdown link paths for TanStack website routing + * + * GitHub markdown links work differently from our router structure: + * - In GitHub: ./guides/foo.md works from docs/overview.md + * - In our router: we need ../guides/foo because the current path is /lib/version/docs/overview (not overview/) + * + * @param path The original markdown link path + * @returns The normalized path for website routing + */ +export function normalizeMarkdownPath(path: string | undefined): string | undefined { + if (!path) return path + + // Don't modify: + // - Absolute paths (/) + // - Paths already using ../ + // - External links (http/https) + // - Hash-only links (#) + // - Special protocols (mailto:, javascript:, etc) + if ( + path.startsWith('/') || + path.startsWith('../') || + path.startsWith('http') || + path.startsWith('#') || + path.includes(':') // Catches mailto:, javascript:, etc + ) { + return path + } + + // Convert ./path to ../path (GitHub style to website style) + if (path.startsWith('./')) { + return '../' + path.slice(2) + } + + // Handle bare paths (no ./ prefix) + // These are treated as siblings, so prepend ../ + // This covers: + // - "foo" (same directory file) + // - "guides/foo" (subdirectory) + return '../' + path +} \ No newline at end of file