mirror of
https://github.com/waynesutton/markdown-site.git
synced 2026-01-12 04:09:14 +00:00
fix: docs scroll
This commit is contained in:
@@ -22,7 +22,7 @@ Your content is instantly available to browsers, LLMs, and AI agents.. Write mar
|
|||||||
- **Total Posts**: 17
|
- **Total Posts**: 17
|
||||||
- **Total Pages**: 5
|
- **Total Pages**: 5
|
||||||
- **Latest Post**: 2025-12-29
|
- **Latest Post**: 2025-12-29
|
||||||
- **Last Updated**: 2025-12-30T08:48:17.735Z
|
- **Last Updated**: 2025-12-30T20:03:38.734Z
|
||||||
|
|
||||||
## Tech stack
|
## Tech stack
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ Project instructions for Claude Code.
|
|||||||
|
|
||||||
## Project context
|
## Project context
|
||||||
|
|
||||||
|
<!-- Auto-updated by sync:discovery -->
|
||||||
|
<!-- Site: markdown | Posts: 17 | Pages: 5 | Updated: 2025-12-30T20:03:38.736Z -->
|
||||||
|
|
||||||
Markdown sync framework. Write markdown in `content/`, run sync commands, content appears instantly via Convex real-time database. Built for developers and AI agents.
|
Markdown sync framework. Write markdown in `content/`, run sync commands, content appears instantly via Convex real-time database. Built for developers and AI agents.
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ title: "Changelog"
|
|||||||
slug: "changelog"
|
slug: "changelog"
|
||||||
published: true
|
published: true
|
||||||
order: 5
|
order: 5
|
||||||
|
rightSidebar: true
|
||||||
layout: "sidebar"
|
layout: "sidebar"
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -190,6 +191,7 @@ Released December 29, 2025
|
|||||||
- Works with all four themes (dark, light, tan, cloud)
|
- Works with all four themes (dark, light, tan, cloud)
|
||||||
|
|
||||||
Updated files: `src/components/ContactForm.tsx`, `src/components/NewsletterSignup.tsx`
|
Updated files: `src/components/ContactForm.tsx`, `src/components/NewsletterSignup.tsx`
|
||||||
|
|
||||||
- Honeypot fields use CSS positioning (position: absolute, left: -9999px) to hide from users
|
- Honeypot fields use CSS positioning (position: absolute, left: -9999px) to hide from users
|
||||||
- Fields include aria-hidden="true" and tabIndex={-1} for accessibility
|
- Fields include aria-hidden="true" and tabIndex={-1} for accessibility
|
||||||
- Different field names per form (website/fax) to avoid pattern detection
|
- Different field names per form (website/fax) to avoid pattern detection
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# llms.txt - Information for AI assistants and LLMs
|
# llms.txt - Information for AI assistants and LLMs
|
||||||
# Learn more: https://llmstxt.org/
|
# Learn more: https://llmstxt.org/
|
||||||
# Last updated: 2025-12-30T08:48:17.736Z
|
# Last updated: 2025-12-30T20:03:38.736Z
|
||||||
|
|
||||||
> Your content is instantly available to browsers, LLMs, and AI agents.
|
> Your content is instantly available to browsers, LLMs, and AI agents.
|
||||||
|
|
||||||
|
|||||||
@@ -189,6 +189,7 @@ Released December 29, 2025
|
|||||||
- Works with all four themes (dark, light, tan, cloud)
|
- Works with all four themes (dark, light, tan, cloud)
|
||||||
|
|
||||||
Updated files: `src/components/ContactForm.tsx`, `src/components/NewsletterSignup.tsx`
|
Updated files: `src/components/ContactForm.tsx`, `src/components/NewsletterSignup.tsx`
|
||||||
|
|
||||||
- Honeypot fields use CSS positioning (position: absolute, left: -9999px) to hide from users
|
- Honeypot fields use CSS positioning (position: absolute, left: -9999px) to hide from users
|
||||||
- Fields include aria-hidden="true" and tabIndex={-1} for accessibility
|
- Fields include aria-hidden="true" and tabIndex={-1} for accessibility
|
||||||
- Different field names per form (website/fax) to avoid pattern detection
|
- Different field names per form (website/fax) to avoid pattern detection
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import NewsletterAdmin from "./pages/NewsletterAdmin";
|
|||||||
import Dashboard from "./pages/Dashboard";
|
import Dashboard from "./pages/Dashboard";
|
||||||
import Callback from "./pages/Callback";
|
import Callback from "./pages/Callback";
|
||||||
import Layout from "./components/Layout";
|
import Layout from "./components/Layout";
|
||||||
|
import ScrollToTopOnNav from "./components/ScrollToTopOnNav";
|
||||||
import { usePageTracking } from "./hooks/usePageTracking";
|
import { usePageTracking } from "./hooks/usePageTracking";
|
||||||
import { SidebarProvider } from "./context/SidebarContext";
|
import { SidebarProvider } from "./context/SidebarContext";
|
||||||
import siteConfig from "./config/siteConfig";
|
import siteConfig from "./config/siteConfig";
|
||||||
@@ -45,6 +46,7 @@ function App() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarProvider>
|
<SidebarProvider>
|
||||||
|
<ScrollToTopOnNav />
|
||||||
<Layout>
|
<Layout>
|
||||||
<Routes>
|
<Routes>
|
||||||
{/* Homepage route - either default Home or custom page/post */}
|
{/* Homepage route - either default Home or custom page/post */}
|
||||||
|
|||||||
@@ -99,10 +99,15 @@ export default function AIChatView({
|
|||||||
initChat();
|
initChat();
|
||||||
}, [sessionId, contextId, getOrCreateChat]);
|
}, [sessionId, contextId, getOrCreateChat]);
|
||||||
|
|
||||||
// Auto-scroll to bottom when new messages arrive
|
// Auto-scroll to bottom when new messages arrive (only if there are messages)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (messagesEndRef.current) {
|
// Only scroll if there are actual messages (don't scroll on initial empty state)
|
||||||
messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
|
if (messagesEndRef.current && chat?.messages && chat.messages.length > 0) {
|
||||||
|
// Use scrollTo on the parent container instead of scrollIntoView to avoid page scroll
|
||||||
|
const messagesContainer = messagesEndRef.current.parentElement;
|
||||||
|
if (messagesContainer) {
|
||||||
|
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [chat?.messages]);
|
}, [chat?.messages]);
|
||||||
|
|
||||||
|
|||||||
22
src/components/ScrollToTopOnNav.tsx
Normal file
22
src/components/ScrollToTopOnNav.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { useLayoutEffect } from "react";
|
||||||
|
import { useLocation } from "react-router-dom";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scrolls to top of page on route changes
|
||||||
|
* Skips scroll if navigating to a hash anchor
|
||||||
|
* Uses useLayoutEffect to run before browser paint
|
||||||
|
*/
|
||||||
|
export default function ScrollToTopOnNav() {
|
||||||
|
const { pathname, hash } = useLocation();
|
||||||
|
|
||||||
|
// useLayoutEffect runs synchronously before browser paint
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
// Skip if navigating to a hash anchor
|
||||||
|
if (hash) return;
|
||||||
|
|
||||||
|
// Scroll to top immediately (before paint)
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
}, [pathname, hash]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
@@ -7,6 +7,11 @@ import { FontProvider } from "./context/FontContext";
|
|||||||
import { isWorkOSConfigured } from "./utils/workos";
|
import { isWorkOSConfigured } from "./utils/workos";
|
||||||
import "./styles/global.css";
|
import "./styles/global.css";
|
||||||
|
|
||||||
|
// Disable browser scroll restoration to prevent scroll position being restored on navigation
|
||||||
|
if ("scrollRestoration" in window.history) {
|
||||||
|
window.history.scrollRestoration = "manual";
|
||||||
|
}
|
||||||
|
|
||||||
const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL);
|
const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL);
|
||||||
|
|
||||||
// Lazy load the appropriate App wrapper based on WorkOS configuration
|
// Lazy load the appropriate App wrapper based on WorkOS configuration
|
||||||
|
|||||||
Reference in New Issue
Block a user