diff --git a/src/pages/llms-full.txt.ts b/src/pages/llms-full.txt.ts new file mode 100644 index 0000000..77e2548 --- /dev/null +++ b/src/pages/llms-full.txt.ts @@ -0,0 +1,82 @@ +import type { APIRoute } from 'astro'; +import { getCollection } from 'astro:content'; +import { SITE_TITLE, SITE_DESCRIPTION } from '../consts'; + +export const prerender = true; + +export const GET: APIRoute = async (context) => { + const site = context.site?.toString().replace(/\/$/, '') ?? 'https://nicholai.work'; + + // Fetch and sort blog posts by date (newest first) + const posts = (await getCollection('blog')).sort( + (a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf() + ); + + // Build llms-full.txt content with full post bodies + const lines: string[] = [ + `# ${SITE_TITLE}`, + '', + `> ${SITE_DESCRIPTION}`, + '', + '## About This File', + '', + 'This file contains the full content of all blog posts on this site, formatted for LLM consumption.', + 'For a shorter index of available content, see /llms.txt', + '', + '## Pages', + '', + `- [Home](${site}/)`, + `- [Blog](${site}/blog/)`, + `- [Contact](${site}/contact/)`, + '', + '---', + '', + '## Blog Posts', + '', + ]; + + // Add each blog post with full content + for (const post of posts) { + const url = `${site}/blog/${post.id}/`; + const date = post.data.pubDate.toISOString().split('T')[0]; + const category = post.data.category ?? 'Uncategorized'; + const tags = post.data.tags?.join(', ') ?? ''; + + lines.push(`### ${post.data.title}`); + lines.push(''); + lines.push(`- **URL**: ${url}`); + lines.push(`- **Date**: ${date}`); + lines.push(`- **Category**: ${category}`); + if (tags) { + lines.push(`- **Tags**: ${tags}`); + } + lines.push(`- **Description**: ${post.data.description}`); + lines.push(''); + lines.push('#### Content'); + lines.push(''); + // Include the raw body content (MDX source) + if (post.body) { + lines.push(post.body); + } else { + lines.push('*No content body available*'); + } + lines.push(''); + lines.push('---'); + lines.push(''); + } + + lines.push('## Additional Resources'); + lines.push(''); + lines.push(`- [RSS Feed](${site}/rss.xml)`); + lines.push(`- [Sitemap](${site}/sitemap-index.xml)`); + lines.push(''); + + const body = lines.join('\n'); + + return new Response(body, { + headers: { + 'Content-Type': 'text/plain; charset=utf-8', + }, + }); +}; + diff --git a/src/pages/llms.txt.ts b/src/pages/llms.txt.ts new file mode 100644 index 0000000..6a7085b --- /dev/null +++ b/src/pages/llms.txt.ts @@ -0,0 +1,54 @@ +import type { APIRoute } from 'astro'; +import { getCollection } from 'astro:content'; +import { SITE_TITLE, SITE_DESCRIPTION } from '../consts'; + +export const prerender = true; + +export const GET: APIRoute = async (context) => { + const site = context.site?.toString().replace(/\/$/, '') ?? 'https://nicholai.work'; + + // Fetch and sort blog posts by date (newest first) + const posts = (await getCollection('blog')).sort( + (a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf() + ); + + // Build llms.txt content following the standard format + const lines: string[] = [ + `# ${SITE_TITLE}`, + '', + `> ${SITE_DESCRIPTION}`, + '', + '## Pages', + '', + `- [Home](${site}/)`, + `- [Blog](${site}/blog/)`, + `- [Contact](${site}/contact/)`, + '', + '## Blog Posts', + '', + ]; + + // Add each blog post + for (const post of posts) { + const url = `${site}/blog/${post.id}/`; + const date = post.data.pubDate.toISOString().split('T')[0]; + lines.push(`- [${post.data.title}](${url}) - ${date}`); + } + + lines.push(''); + lines.push('## Additional Resources'); + lines.push(''); + lines.push(`- [RSS Feed](${site}/rss.xml)`); + lines.push(`- [Sitemap](${site}/sitemap-index.xml)`); + lines.push(`- [Full LLM Context](${site}/llms-full.txt)`); + lines.push(''); + + const body = lines.join('\n'); + + return new Response(body, { + headers: { + 'Content-Type': 'text/plain; charset=utf-8', + }, + }); +}; + diff --git a/src/styles/global.css b/src/styles/global.css index 5e0c657..ecba4e1 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -288,26 +288,27 @@ html { left: 0; transform: translate(-50%, -50%); border-radius: 50%; - z-index: 9999; pointer-events: none; will-change: transform; } -.cursor-dot { - width: 8px; - height: 8px; - background-color: var(--color-brand-accent); -} - .cursor-outline { width: 40px; height: 40px; border: 1px solid rgba(255, 77, 0, 0.5); + z-index: 99999; transition: width 0.3s cubic-bezier(0.16, 1, 0.3, 1), height 0.3s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.3s ease; } +.cursor-dot { + width: 8px; + height: 8px; + background-color: var(--color-brand-accent); + z-index: 999999; +} + /* Interactive Elements Cursor Hover Effect */ .hover-trigger:hover~.cursor-outline, a:hover~.cursor-outline,