diff --git a/.claude/skills/dev.md b/.claude/skills/dev.md index b25e3df..fca4fef 100644 --- a/.claude/skills/dev.md +++ b/.claude/skills/dev.md @@ -69,6 +69,17 @@ Expert full-stack and AI developer specializing in React, Vite, Bun, Clerk, Work - PRD files end in `.MD` and go in `prds/` folder - Do NOT create README, CONTRIBUTING, SUMMARY, or USAGE_GUIDELINES unless explicitly asked +## Git safety + +Follow all rules in `.claude/skills/gitrules.md`: + +- Never use `git checkout` to revert changes without examining what will be destroyed +- Always use `git diff ` before any destructive operation +- Never run destructive commands (`git reset --hard`, `git checkout -- .`, `git clean -fd`, `git stash drop`) without explicit user approval +- Always run `git status` first before any git operation +- When asked to "undo" changes, manually edit files instead of using checkout +- If uncommitted changes exist, stop and ask user before proceeding + ## Communication - Give answers immediately, explain after diff --git a/.claude/skills/help.md b/.claude/skills/help.md index 9deb929..ff295fa 100644 --- a/.claude/skills/help.md +++ b/.claude/skills/help.md @@ -102,6 +102,16 @@ Don't write any code until you're very confident (98% or more) in what needs to If unclear, ask for more information. +## 7. Git safety + +Follow all rules in `.claude/skills/gitrules.md`: + +- Never use `git checkout` to revert changes without examining what will be destroyed +- Always use `git diff ` before any destructive operation +- Never run `git reset --hard`, `git checkout -- .`, `git clean -fd`, or `git stash drop` without explicit user approval +- Always run `git status` first to check for uncommitted changes +- When user asks to "undo" changes, manually edit files to revert specific sections instead of using checkout + ## Quick reference checklist Before writing code: @@ -119,3 +129,10 @@ When uncertain: - [ ] Don't assume - [ ] Reference documentation - [ ] Narrow down to 1-2 most likely solutions + +Before git operations: +- [ ] Have I run `git status` first? +- [ ] Am I about to run a destructive command? +- [ ] Have I shown the user what will be affected? +- [ ] Do I have explicit user approval for destructive operations? +- [ ] Am I following `.claude/skills/gitrules.md`? diff --git a/.cursor/rules/dev2.mdc b/.cursor/rules/dev2.mdc index dcda786..89cb00d 100644 --- a/.cursor/rules/dev2.mdc +++ b/.cursor/rules/dev2.mdc @@ -19,7 +19,7 @@ alwaysApply: true -Do you understand, what I’m asking? Never assume anything on your own, if anything isn’t clear, please ask questions and clarify your doubts. -- reference @dev2.mdc @help.mdc @files.md if needed +- reference @dev2.mdc @help.mdc @gitruels.mdc @files.md if needed - do not use use emoji or emojis in the readme or app unless instructed - always create type-safe code - you understand when to use Effect and when not to use Effect https://react.dev/learn/you-might-not-need-an-effect @@ -82,3 +82,4 @@ alwaysApply: true - you never use placeholder text or images in code because everything is realtime sync with convex database - you don't ship code with placeholder text or images - **!IMPORTANT**: **DO NOT** externalize or document your work, usage guidelines, or benchmarks (e.g. `README.md`, `CONTRIBUTING.md`, `SUMMARY.md`, `USAGE_GUIDELINES.md` after completing the task, unless explicitly instructed to do so. You may include a brief summary of your work, but do not create separate documentation files for it. +- **!IMPORTANT**: Follow all git safety rules in @gitruels.mdc - never use destructive git commands without explicit user approval, always run `git status` first, and manually edit files instead of using `git checkout` to revert changes. diff --git a/.cursor/rules/help.mdc b/.cursor/rules/help.mdc index 37aa803..a66052a 100644 --- a/.cursor/rules/help.mdc +++ b/.cursor/rules/help.mdc @@ -85,3 +85,16 @@ When making changes to the codebase: Don't write any code until you're very confident (98% or more) in what needs to be done. If unclear, ask for more info. + +⸻ + +## 7. Git Safety + +Follow all rules in @gitruels.mdc: + +- Never use `git checkout` to revert changes without examining what will be destroyed +- Always use `git diff ` before any destructive operation +- Never run destructive commands (`git reset --hard`, `git checkout -- .`, `git clean -fd`, `git stash drop`) without explicit user approval +- Always run `git status` first before any git operation +- When asked to "undo" changes, manually edit files instead of using checkout +- If uncommitted changes exist, stop and ask user before proceeding diff --git a/AGENTS.md b/AGENTS.md index 0affaad..04dd670 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,10 +19,10 @@ Your content is instantly available to browsers, LLMs, and AI agents.. Write mar - **Site Name**: markdown - **Site Title**: markdown sync framework - **Site URL**: https://yoursite.example.com -- **Total Posts**: 17 +- **Total Posts**: 18 - **Total Pages**: 4 -- **Latest Post**: 2025-12-29 -- **Last Updated**: 2026-01-07T06:23:37.520Z +- **Latest Post**: 2026-01-07 +- **Last Updated**: 2026-01-09T07:02:12.472Z ## Tech stack diff --git a/CLAUDE.md b/CLAUDE.md index 90fbe97..9093d3c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5,7 +5,7 @@ Project instructions for Claude Code. ## Project context - + Markdown sync framework. Write markdown in `content/`, run sync commands, content appears instantly via Convex real-time database. Built for developers and AI agents. diff --git a/TASK.md b/TASK.md index f3b7214..ff5d170 100644 --- a/TASK.md +++ b/TASK.md @@ -4,10 +4,18 @@ ## Current Status -v2.15.1 ready. Additional Core Web Vitals CLS and INP improvements. +v2.15.3 ready. Fixed footer not displaying on docs landing page. ## Completed +- [x] Footer not displaying on /docs landing page fix (v2.15.3) + - [x] DocsPage.tsx was missing Footer component entirely + - [x] Added Footer import and footerPage query to DocsPage.tsx + - [x] Added footer rendering logic after BlogPost (same pattern as Post.tsx) + - [x] Updated getDocsLandingPage query to return showFooter, footer, excerpt, aiChat fields + - [x] Updated getDocsLandingPost query to return showFooter, footer, aiChat fields + - [x] Added aiChatEnabled and pageContent props to DocsLayout + - [x] Additional Core Web Vitals CLS and INP improvements (v2.15.1) - [x] Added aspect-ratio to blog images and header images to prevent layout shift - [x] Added CSS containment to main content areas diff --git a/changelog.md b/changelog.md index 2a89cec..fc0f48d 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [2.15.3] - 2026-01-09 + +### Fixed + +- Footer not displaying on `/docs` landing page when `showFooter: true` in frontmatter + - `DocsPage.tsx` was missing the Footer component entirely + - Added Footer import, footerPage query, and footer rendering logic to DocsPage.tsx + - Footer now respects `showFooter` frontmatter field on docs landing pages + - AI chat support added to DocsLayout via `aiChatEnabled` and `pageContent` props + +### Changed + +- Updated `getDocsLandingPage` query in `convex/pages.ts` to return `showFooter`, `footer`, `excerpt`, and `aiChat` fields +- Updated `getDocsLandingPost` query in `convex/posts.ts` to return `showFooter`, `footer`, and `aiChat` fields + ## [2.15.2] - 2026-01-08 ### Fixed diff --git a/content/pages/changelog-page.md b/content/pages/changelog-page.md index 43295ab..136c847 100644 --- a/content/pages/changelog-page.md +++ b/content/pages/changelog-page.md @@ -11,6 +11,35 @@ docsSectionOrder: 4 All notable changes to this project. +## v2.15.3 + +Released January 9, 2026 + +**Footer not displaying on /docs landing page fix** + +Fixed an issue where the footer was not displaying on the `/docs` landing page even when `showFooter: true` was set in the frontmatter. The `DocsPage.tsx` component (which handles the `/docs` route with `docsLanding: true`) was missing the Footer component entirely. + +**Fixes:** + +- Added Footer component to DocsPage.tsx +- Footer now respects `showFooter` frontmatter field on docs landing pages +- Added AI chat support to docs landing page via `aiChatEnabled` and `pageContent` props + +**Technical:** + +- Added `Footer` import and `footerPage` query to fetch footer content +- Added footer rendering logic after BlogPost component (same pattern as Post.tsx) +- Updated `getDocsLandingPage` query in `convex/pages.ts` to return `showFooter`, `footer`, `excerpt`, and `aiChat` fields +- Updated `getDocsLandingPost` query in `convex/posts.ts` to return `showFooter`, `footer`, and `aiChat` fields + +**Files changed:** + +- `src/pages/DocsPage.tsx` - Added Footer component and rendering logic +- `convex/pages.ts` - Updated getDocsLandingPage query return fields +- `convex/posts.ts` - Updated getDocsLandingPost query return fields + +--- + ## v2.15.2 Released January 8, 2026 diff --git a/convex/pages.ts b/convex/pages.ts index 6ebebf2..7d66583 100644 --- a/convex/pages.ts +++ b/convex/pages.ts @@ -283,12 +283,16 @@ export const getDocsLandingPage = query({ slug: v.string(), title: v.string(), content: v.string(), + excerpt: v.optional(v.string()), image: v.optional(v.string()), showImageAtTop: v.optional(v.boolean()), authorName: v.optional(v.string()), authorImage: v.optional(v.string()), docsSectionGroup: v.optional(v.string()), docsSectionOrder: v.optional(v.number()), + showFooter: v.optional(v.boolean()), + footer: v.optional(v.string()), + aiChat: v.optional(v.boolean()), }), v.null(), ), @@ -308,12 +312,16 @@ export const getDocsLandingPage = query({ slug: landing.slug, title: landing.title, content: landing.content, + excerpt: landing.excerpt, image: landing.image, showImageAtTop: landing.showImageAtTop, authorName: landing.authorName, authorImage: landing.authorImage, docsSectionGroup: landing.docsSectionGroup, docsSectionOrder: landing.docsSectionOrder, + showFooter: landing.showFooter, + footer: landing.footer, + aiChat: landing.aiChat, }; }, }); diff --git a/convex/posts.ts b/convex/posts.ts index 7ed20b3..ea6e427 100644 --- a/convex/posts.ts +++ b/convex/posts.ts @@ -977,6 +977,9 @@ export const getDocsLandingPost = query({ authorImage: v.optional(v.string()), docsSectionGroup: v.optional(v.string()), docsSectionOrder: v.optional(v.number()), + showFooter: v.optional(v.boolean()), + footer: v.optional(v.string()), + aiChat: v.optional(v.boolean()), }), v.null(), ), @@ -1006,6 +1009,9 @@ export const getDocsLandingPost = query({ authorImage: landing.authorImage, docsSectionGroup: landing.docsSectionGroup, docsSectionOrder: landing.docsSectionOrder, + showFooter: landing.showFooter, + footer: landing.footer, + aiChat: landing.aiChat, }; }, }); diff --git a/files.md b/files.md index 60c14d1..8bbf155 100644 --- a/files.md +++ b/files.md @@ -45,6 +45,7 @@ A brief description of each file in the codebase. | `Blog.tsx` | Dedicated blog page with featured layout: hero post (first blogFeatured), featured row (remaining blogFeatured in 2 columns with excerpts), and regular posts (3 columns without excerpts). Supports list/card view toggle. Includes back button in navigation | | `Post.tsx` | Individual blog post or page view with optional left sidebar (TOC) and right sidebar (CopyPageDropdown). Includes back button (hidden when used as homepage), tag links, related posts section in footer for blog posts, footer component with markdown support (fetches footer.md content from Convex), and social footer. Supports 3-column layout at 1135px+. Can display image at top when showImageAtTop: true. Can be used as custom homepage via siteConfig.homepage (update SITE_URL/SITE_NAME when forking). SEO: Dynamic canonical URL, hreflang tags, og:url consistency, and twitter:site meta tags. DOM order optimized for SEO (article before sidebar, CSS order for visual layout). | | `Stats.tsx` | Real-time analytics dashboard with visitor stats and GitHub stars. Configurable via `siteConfig.statsPage` to enable/disable public access and navigation visibility. Shows disabled message when `enabled: false` (similar to NewsletterAdmin pattern). | +| `DocsPage.tsx` | Docs landing page component for `/docs` route. Renders the page/post with `docsLanding: true` in DocsLayout. Fetches landing content via `getDocsLandingPage` and `getDocsLandingPost` queries. Includes Footer component (respects showFooter frontmatter), AI chat support (aiChatEnabled), and fallback to first docs item if no landing page is set. | | `TagPage.tsx` | Tag archive page displaying posts filtered by a specific tag. Includes view mode toggle (list/cards) with localStorage persistence | | `AuthorPage.tsx` | Author archive page displaying posts by a specific author. Includes view mode toggle (list/cards) with localStorage persistence. Author name clickable in posts links to this page. | | `Write.tsx` | Three-column markdown writing page with Cursor docs-style UI, frontmatter reference with copy buttons, theme toggle, font switcher (serif/sans/monospace), localStorage persistence, and optional AI Agent mode (toggleable via siteConfig.aiChat.enabledOnWritePage). When enabled, Agent replaces the textarea with AIChatView component. Includes scroll prevention when switching to Agent mode to prevent page jump. Title changes to "Agent" when in AI chat mode. | diff --git a/index.html b/index.html index 74da31c..347f8b1 100644 --- a/index.html +++ b/index.html @@ -10,6 +10,8 @@ + + diff --git a/public/llms.txt b/public/llms.txt index 9aff604..1bc8926 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -1,6 +1,6 @@ # llms.txt - Information for AI assistants and LLMs # Learn more: https://llmstxt.org/ -# Last updated: 2026-01-07T06:23:37.522Z +# Last updated: 2026-01-09T07:02:12.474Z > Your content is instantly available to browsers, LLMs, and AI agents. @@ -9,8 +9,8 @@ - URL: https://yoursite.example.com - Description: Your content is instantly available to browsers, LLMs, and AI agents. Write markdown, sync from the terminal. Your content is instantly available to browsers, LLMs, and AI agents. Built on Convex and Netlify. - Topics: Markdown, Convex, React, TypeScript, Netlify, Open Source, AI, LLM, AEO, GEO -- Total Posts: 17 -- Latest Post: 2025-12-29 +- Total Posts: 18 +- Latest Post: 2026-01-07 - GitHub: https://github.com/waynesutton/markdown-site # API Endpoints diff --git a/src/pages/DocsPage.tsx b/src/pages/DocsPage.tsx index 3efa847..1f88175 100644 --- a/src/pages/DocsPage.tsx +++ b/src/pages/DocsPage.tsx @@ -5,6 +5,7 @@ import { api } from "../../convex/_generated/api"; import DocsLayout from "../components/DocsLayout"; import BlogPost from "../components/BlogPost"; import CopyPageDropdown from "../components/CopyPageDropdown"; +import Footer from "../components/Footer"; import { extractHeadings } from "../utils/extractHeadings"; import siteConfig from "../config/siteConfig"; import { ArrowRight } from "lucide-react"; @@ -21,6 +22,9 @@ export default function DocsPage() { const docsPosts = useQuery(api.posts.getDocsPosts); const docsPages = useQuery(api.pages.getDocsPages); + // Fetch footer content from Convex (synced via markdown) + const footerPage = useQuery(api.pages.getPageBySlug, { slug: "footer" }); + // Determine which content to use: page takes priority over post const landingContent = landingPage || landingPost; @@ -76,7 +80,12 @@ export default function DocsPage() { : undefined; return ( - +
+ {/* Footer - respects showFooter frontmatter field */} + {siteConfig.footer.enabled && + (landingContent.showFooter !== undefined + ? landingContent.showFooter + : "date" in landingContent + ? siteConfig.footer.showOnPosts + : siteConfig.footer.showOnPages) && ( +
+ )}
); diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index ccd5bc7..60327a9 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -170,6 +170,9 @@ export default function Home() { src={siteConfig.logo} alt={siteConfig.name} className="home-logo" + width={48} + height={48} + fetchPriority="high" /> )}

{siteConfig.name}

diff --git a/src/styles/global.css b/src/styles/global.css index 5f6685f..e624ef2 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -12941,6 +12941,7 @@ body { min-height: calc(100vh - 60px); margin: 0; padding: 0; + contain: layout style; /* CLS fix: isolate layout recalculations */ } /* Docs layout without TOC (two-column) */ @@ -12948,19 +12949,19 @@ body { /* Same as default - sidebars are fixed */ } -/* Left sidebar for docs navigation - flush left */ +/* Left sidebar for docs navigation - flush left, full height */ .docs-sidebar-left { position: fixed; - top: 20px; + top: 0; + bottom: 0; left: 0; width: 280px; - height: calc(100vh - 80px); + height: 100%; overflow-y: auto; background-color: var(--bg-sidebar); padding: 24px; + padding-top: 32px; border-right: 1px solid var(--border-sidebar); - border-radius: 6px; - border-top: 1px solid var(--border-sidebar); z-index: 10; } @@ -12981,19 +12982,19 @@ body { background-color: var(--text-muted); } -/* Right sidebar for table of contents - flush right */ +/* Right sidebar for table of contents - flush right, full height */ .docs-sidebar-right { position: fixed; - top: 20px; + top: 0; + bottom: 0; right: 0; width: 280px; - height: calc(100vh - 80px); + height: 100%; overflow-y: auto; background-color: var(--bg-sidebar); padding: 24px; + padding-top: 32px; border-left: 1px solid var(--border-sidebar); - border-radius: 6px; - border-top: 1px solid var(--border-sidebar); z-index: 10; }