From a490470db69807329bf56c9342cf87e4be3c69d2 Mon Sep 17 00:00:00 2001 From: Atharva Deosthale Date: Mon, 26 Jan 2026 07:31:05 +0530 Subject: [PATCH 1/4] prompt markdoc for quickstarts in ai docs section --- src/lib/components/PromptBanner.svelte | 13 +++- src/lib/layouts/DocsArticle.svelte | 4 +- src/markdoc/layouts/Article.svelte | 5 +- src/markdoc/tags/Prompt.svelte | 78 +++++++++++++++++++ src/markdoc/tags/_Module.svelte | 1 + .../quickstart-prompts/nextjs/+page.markdoc | 3 +- 6 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 src/markdoc/tags/Prompt.svelte diff --git a/src/lib/components/PromptBanner.svelte b/src/lib/components/PromptBanner.svelte index 1d0b82ca9d..9e47ab88e6 100644 --- a/src/lib/components/PromptBanner.svelte +++ b/src/lib/components/PromptBanner.svelte @@ -10,9 +10,16 @@ import AiPromptIcon from '$lib/components/ui/aiPromptIcon.svelte'; import { browser } from '$app/environment'; - // Only support co-located prompt.md - const routeExists = hasRoutePrompt(); - const prompt = routeExists ? (getRoutePrompt() ?? '') : ''; + // Optional path to a prompt located elsewhere (e.g., "/docs/quick-starts/nextjs") + // If not provided, falls back to co-located prompt.md for current page + interface Props { + promptPath?: string; + } + let { promptPath }: Props = $props(); + + // Support co-located prompt.md or prompt from a different route via promptPath + const routeExists = hasRoutePrompt(promptPath); + const prompt = routeExists ? (getRoutePrompt(promptPath) ?? '') : ''; const exists = routeExists; const { copied, copy } = createCopy(prompt); diff --git a/src/lib/layouts/DocsArticle.svelte b/src/lib/layouts/DocsArticle.svelte index 18c093f560..820b0fde96 100644 --- a/src/lib/layouts/DocsArticle.svelte +++ b/src/lib/layouts/DocsArticle.svelte @@ -33,13 +33,15 @@ export let toc: Array; export let back: string | undefined = undefined; export let date: string | undefined = undefined; + export let promptPath: string | undefined = undefined; const reducedArticleSize = setContext('articleHasNumericBadge', writable(false)); const headerSectionInfoAlert = hasContext('headerSectionInfoAlert') ? getContext>('headerSectionInfoAlert') : readable(null); - const showCopyPage = !hasRoutePrompt(); + // Hide "Copy Page" button if a prompt exists (either co-located or via promptPath) + const showCopyPage = !hasRoutePrompt(promptPath);
diff --git a/src/markdoc/layouts/Article.svelte b/src/markdoc/layouts/Article.svelte index 3006def0ff..c57fd0bbaf 100644 --- a/src/markdoc/layouts/Article.svelte +++ b/src/markdoc/layouts/Article.svelte @@ -30,6 +30,7 @@ export let difficulty: string | undefined = undefined; export let readtime: string | undefined = undefined; export let date: string | undefined = undefined; + export let prompt: string | undefined = undefined; setContext('headings', writable({})); @@ -79,7 +80,7 @@ - + {#if difficulty}
  • {difficulty}
  • @@ -88,7 +89,7 @@
  • {readtime} min
  • {/if}
    - +
    diff --git a/src/markdoc/tags/Prompt.svelte b/src/markdoc/tags/Prompt.svelte new file mode 100644 index 0000000000..1f3178408c --- /dev/null +++ b/src/markdoc/tags/Prompt.svelte @@ -0,0 +1,78 @@ + + +{#if renderedHtml} +
    + {@html renderedHtml} +
    +{:else} +

    No prompt found for route: {route}

    +{/if} + + diff --git a/src/markdoc/tags/_Module.svelte b/src/markdoc/tags/_Module.svelte index a7a8022ac1..ab6a3b2dbf 100644 --- a/src/markdoc/tags/_Module.svelte +++ b/src/markdoc/tags/_Module.svelte @@ -23,4 +23,5 @@ export { default as Storage_Image } from './Storage_Image.svelte'; export { default as Video_Card } from './Video_Card.svelte'; export { default as Appwrite_Network_Map } from '../../lib/components/appwrite-network/map.svelte'; + export { default as Prompt } from './Prompt.svelte'; diff --git a/src/routes/docs/tooling/ai/quickstart-prompts/nextjs/+page.markdoc b/src/routes/docs/tooling/ai/quickstart-prompts/nextjs/+page.markdoc index 51295b758b..907ea9818d 100644 --- a/src/routes/docs/tooling/ai/quickstart-prompts/nextjs/+page.markdoc +++ b/src/routes/docs/tooling/ai/quickstart-prompts/nextjs/+page.markdoc @@ -2,6 +2,7 @@ layout: article title: Next.js description: Quickstart prompt for integrating Appwrite with Next.js. +prompt: /docs/quick-starts/nextjs --- -Quickstart prompt for integrating Appwrite with Next.js. +{% prompt route="/docs/quick-starts/nextjs" /%} \ No newline at end of file From bcd13fa4f21699c78b40224a40e33ed1927afdc5 Mon Sep 17 00:00:00 2001 From: Atharva Deosthale Date: Mon, 26 Jan 2026 07:43:54 +0530 Subject: [PATCH 2/4] need to figure out partials for prompts --- src/markdoc/tags/Prompt.svelte | 78 --------------------------------- src/markdoc/tags/_Module.svelte | 1 - 2 files changed, 79 deletions(-) delete mode 100644 src/markdoc/tags/Prompt.svelte diff --git a/src/markdoc/tags/Prompt.svelte b/src/markdoc/tags/Prompt.svelte deleted file mode 100644 index 1f3178408c..0000000000 --- a/src/markdoc/tags/Prompt.svelte +++ /dev/null @@ -1,78 +0,0 @@ - - -{#if renderedHtml} -
    - {@html renderedHtml} -
    -{:else} -

    No prompt found for route: {route}

    -{/if} - - diff --git a/src/markdoc/tags/_Module.svelte b/src/markdoc/tags/_Module.svelte index ab6a3b2dbf..a7a8022ac1 100644 --- a/src/markdoc/tags/_Module.svelte +++ b/src/markdoc/tags/_Module.svelte @@ -23,5 +23,4 @@ export { default as Storage_Image } from './Storage_Image.svelte'; export { default as Video_Card } from './Video_Card.svelte'; export { default as Appwrite_Network_Map } from '../../lib/components/appwrite-network/map.svelte'; - export { default as Prompt } from './Prompt.svelte'; From efd4d981acb3a18fe55b91ee0303dd2fa1fe4462 Mon Sep 17 00:00:00 2001 From: Atharva Deosthale Date: Mon, 26 Jan 2026 07:47:25 +0530 Subject: [PATCH 3/4] remove prompt markdoc example --- .../docs/tooling/ai/quickstart-prompts/nextjs/+page.markdoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/routes/docs/tooling/ai/quickstart-prompts/nextjs/+page.markdoc b/src/routes/docs/tooling/ai/quickstart-prompts/nextjs/+page.markdoc index 907ea9818d..cddab4a779 100644 --- a/src/routes/docs/tooling/ai/quickstart-prompts/nextjs/+page.markdoc +++ b/src/routes/docs/tooling/ai/quickstart-prompts/nextjs/+page.markdoc @@ -4,5 +4,3 @@ title: Next.js description: Quickstart prompt for integrating Appwrite with Next.js. prompt: /docs/quick-starts/nextjs --- - -{% prompt route="/docs/quick-starts/nextjs" /%} \ No newline at end of file From 1a125fd5884f7e652ee2cea60563f8dfa69c670c Mon Sep 17 00:00:00 2001 From: Atharva Deosthale Date: Tue, 27 Jan 2026 09:21:27 +0530 Subject: [PATCH 4/4] promptAsContent flag --- src/lib/preprocessors/promptAsContent.js | 68 +++++++++++++++++++ .../quickstart-prompts/nextjs/+page.markdoc | 1 + svelte.config.js | 2 + 3 files changed, 71 insertions(+) create mode 100644 src/lib/preprocessors/promptAsContent.js diff --git a/src/lib/preprocessors/promptAsContent.js b/src/lib/preprocessors/promptAsContent.js new file mode 100644 index 0000000000..498259b4c0 --- /dev/null +++ b/src/lib/preprocessors/promptAsContent.js @@ -0,0 +1,68 @@ +import { readFileSync, existsSync } from 'fs'; +import { join, dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const routesDir = join(__dirname, '../../routes'); + +/** + * Svelte preprocessor that injects prompt.md content into markdoc files + * when `promptAsContent: true` is set in the frontmatter. + * + * @returns {import('svelte/compiler').PreprocessorGroup} + */ +export function promptAsContentPreprocessor() { + return { + name: 'prompt-as-content', + markup({ content, filename }) { + // Only process .markdoc files + if (!filename?.endsWith('.markdoc')) { + return; + } + + // Check for promptAsContent in frontmatter + const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/); + if (!frontmatterMatch) { + return; + } + + const frontmatter = frontmatterMatch[1]; + + // Check if promptAsContent is true + if (!/promptAsContent:\s*true/.test(frontmatter)) { + return; + } + + // Extract the prompt path + const promptMatch = frontmatter.match(/prompt:\s*(.+)/); + if (!promptMatch) { + console.warn( + `[prompt-as-content] promptAsContent is true but no prompt path found in ${filename}` + ); + return; + } + + const promptPath = promptMatch[1].trim(); + // Convert route path like "/docs/quick-starts/nextjs" to file path + const promptFilePath = join(routesDir, promptPath.replace(/^\//, ''), 'prompt.md'); + + if (!existsSync(promptFilePath)) { + console.warn(`[prompt-as-content] prompt.md not found at ${promptFilePath}`); + return; + } + + // Read the prompt content + const promptContent = readFileSync(promptFilePath, 'utf-8'); + + // Inject the prompt content after the frontmatter + const newContent = content.replace( + /^(---\n[\s\S]*?\n---)\n*/, + `$1\n\n${promptContent}\n` + ); + + return { + code: newContent + }; + } + }; +} diff --git a/src/routes/docs/tooling/ai/quickstart-prompts/nextjs/+page.markdoc b/src/routes/docs/tooling/ai/quickstart-prompts/nextjs/+page.markdoc index cddab4a779..d49cd30693 100644 --- a/src/routes/docs/tooling/ai/quickstart-prompts/nextjs/+page.markdoc +++ b/src/routes/docs/tooling/ai/quickstart-prompts/nextjs/+page.markdoc @@ -3,4 +3,5 @@ layout: article title: Next.js description: Quickstart prompt for integrating Appwrite with Next.js. prompt: /docs/quick-starts/nextjs +promptAsContent: true --- diff --git a/svelte.config.js b/svelte.config.js index 5170f11599..a9837e401a 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -4,6 +4,7 @@ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; import { dirname, join } from 'path'; import { markdoc } from 'svelte-markdoc-preprocess'; import { fileURLToPath } from 'url'; +import { promptAsContentPreprocessor } from './src/lib/preprocessors/promptAsContent.js'; /** @type {import('@sveltejs/kit').Config}*/ const config = { @@ -11,6 +12,7 @@ const config = { // for more information about preprocessors preprocess: sequence([ vitePreprocess(), + promptAsContentPreprocessor(), markdoc({ generateSchema: true, nodes: absolute('./src/markdoc/nodes/_Module.svelte'),