fix: remove homepage intro loading flash by using invisible Suspense fallback and null render during query load

This commit is contained in:
Wayne Sutton
2025-12-31 22:08:10 -08:00
parent 86d97e80eb
commit 1e759495eb
17 changed files with 147 additions and 27 deletions

79
.claude/skills/dev.md Normal file
View File

@@ -0,0 +1,79 @@
# Convex Full-Stack Development Skill
Expert full-stack and AI developer specializing in React, Vite, Bun, Clerk, WorkOS, Resend, TypeScript, and Convex.dev.
## Core principles
- Always create type-safe code
- Be terse and casual unless specified otherwise
- No emojis unless instructed
- Treat user as a new developer
- Suggest solutions and anticipate needs
- Never break existing functionality
- Don't over-engineer
## Convex best practices
### Mutations
- Patch directly without reading first
- Use indexed queries for ownership checks (not `ctx.db.get()`)
- Make mutations idempotent with early returns
- Use timestamp-based ordering for new items
- Use `Promise.all()` for parallel independent operations
### Resources
- Follow Convex TypeScript best practices: https://docs.convex.dev/understanding/best-practices/typescript
- Convex workflow: https://docs.convex.dev/understanding/workflow
- Query functions: https://docs.convex.dev/functions/query-functions
- Mutation functions: https://docs.convex.dev/functions/mutation-functions
- Auth functions: https://docs.convex.dev/auth/functions-auth
- File storage: https://docs.convex.dev/file-storage/upload-files
- Vector search: https://docs.convex.dev/search/vector-search
## Authentication
- Expert in WorkOS AuthKit: https://workos.com/docs/authkit/vanilla/nodejs
- Convex + WorkOS setup: https://docs.convex.dev/auth/authkit/
- Clerk integration: https://clerk.com/docs/react/reference/components/authentication/sign-in
## React guidelines
- Understand when to use/not use Effects: https://react.dev/learn/you-might-not-need-an-effect
- Follow React docs: https://react.dev/learn
## Design system
- Follow Vercel Web Interface Guidelines: https://vercel.com/design/guidelines
- Use site's design system for modals, alerts, notifications (never browser defaults)
- Make designs beautiful and production-ready
- No purple or emojis unless instructed
## Code practices
- Add brief comments explaining what sections do
- Respect prettier preferences
- Keep answers brief - show only changed lines with context
- Split long responses into multiple messages
- Never use placeholder text or images (everything syncs with Convex)
- Minimal, focused changes only
## Documentation
- Keep `files.md` with brief file descriptions
- Maintain `changelog.md` following https://keepachangelog.com/en/1.0.0/
- Keep `task.md` tracking completed changes
- Keep `changelog-page.md` updated
- PRD files end in `.MD` and go in `prds/` folder
- Do NOT create README, CONTRIBUTING, SUMMARY, or USAGE_GUIDELINES unless explicitly asked
## Communication
- Give answers immediately, explain after
- Value good arguments over authorities
- Consider new/contrarian ideas
- High speculation is ok (flag it)
- No moral lectures
- Cite sources at the end, not inline
- No need to mention knowledge cutoff or AI disclosure

3
.gitignore vendored
View File

@@ -34,6 +34,9 @@ fork-config.json
# Cursor rules
.cursor/rules/write.mdc
# Claude skills
.claude/skills/write.mdc
# PRD files
prds/metadataforsubs.md
prds/addchattoapp.md

View File

@@ -7,10 +7,16 @@
## Current Status
v2.2.1 ready. ES module compatibility fix for configure-fork.ts. Fixed `__dirname is not defined` error when running `npm run configure`. Added `fileURLToPath` import to create ES module equivalent of `__dirname`. Script now works correctly with `"type": "module"` in package.json.
v2.2.2 ready. Homepage intro loading flash fix. Removed "Loading..." text from Suspense fallback in main.tsx and fixed Home.tsx conditional to render nothing while homeIntro query loads. Home intro content now appears without any visible loading state.
## Completed
- [x] Homepage intro loading flash fix
- [x] Removed "Loading..." text from Suspense fallback in main.tsx
- [x] Fixed Home.tsx conditional to render nothing while homeIntro query loads (undefined vs null)
- [x] Home intro content now appears without any visible loading state or fallback
- [x] Matches loading pattern used by Post.tsx for docs pages
- [x] ES module compatibility fix for configure-fork.ts
- [x] Fixed `__dirname is not defined` error when running `npm run configure`
- [x] Added `fileURLToPath` import from `url` module

View File

@@ -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.2.2] - 2025-12-31
### Fixed
- Homepage intro loading flash
- Removed "Loading..." text from Suspense fallback in main.tsx to prevent flash on app load
- Updated Home.tsx to render nothing while homeIntro query loads (prevents bio text flash)
- Home intro content now appears without any visible loading state or fallback text
- Matches the same loading pattern used by Post.tsx for docs pages
### Technical
- Updated: `src/main.tsx` - Changed LoadingFallback to render empty div instead of "Loading..." text
- Updated: `src/pages/Home.tsx` - Changed conditional from `homeIntro ?` to `homeIntro === undefined ? null : homeIntro ?`
## [2.2.1] - 2025-12-31
### Fixed

View File

@@ -10,6 +10,20 @@ layout: "sidebar"
All notable changes to this project.
![](https://img.shields.io/badge/License-MIT-yellow.svg)
## v2.2.2
Released December 31, 2025
**Homepage intro loading flash fix**
- Removed visible loading states from homepage intro content
- No more "Loading..." text flash when app loads (fixed Suspense fallback in main.tsx)
- No more bio text flash while home intro content loads (fixed conditional in Home.tsx)
- Home intro content now appears without any visible loading state or fallback
- Matches the loading pattern used by Post.tsx for docs pages (render nothing while loading)
Updated files: `src/main.tsx`, `src/pages/Home.tsx`, `changelog.md`, `content/pages/changelog-page.md`, `TASK.md`, `files.md`
## v2.2.1
Released December 31, 2025

View File

@@ -26,7 +26,7 @@ A brief description of each file in the codebase.
| File | Description |
| --------------- | ------------------------------------------------------------------------------------------------ |
| `main.tsx` | React app entry point with conditional WorkOS providers. When WorkOS is configured (VITE_WORKOS_CLIENT_ID and VITE_WORKOS_REDIRECT_URI set), wraps app with AuthKitProvider and ConvexProviderWithAuthKit. When WorkOS is not configured, uses standard ConvexProvider. Uses lazy loading and Suspense for optional WorkOS integration. |
| `main.tsx` | React app entry point with conditional WorkOS providers. When WorkOS is configured (VITE_WORKOS_CLIENT_ID and VITE_WORKOS_REDIRECT_URI set), wraps app with AuthKitProvider and ConvexProviderWithAuthKit. When WorkOS is not configured, uses standard ConvexProvider. Uses lazy loading and Suspense for optional WorkOS integration. Suspense fallback uses invisible div (minHeight: 100vh) to prevent "Loading..." text flash. |
| `App.tsx` | Main app component with routing (supports custom homepage configuration via siteConfig.homepage). Handles /callback route for WorkOS OAuth redirect. |
| `AppWithWorkOS.tsx` | Wrapper component for WorkOS-enabled app. Provides AuthKitProvider and ConvexProviderWithAuthKit. Only loaded when WorkOS is configured. |
| `vite-env.d.ts` | Vite environment type definitions |

View File

@@ -2,7 +2,7 @@
---
Type: page
Date: 2025-12-31
Date: 2026-01-01
---
An open-source publishing framework built for AI agents and developers to ship websites, docs, or blogs.. Write markdown, sync from the terminal. Your content is instantly available to browsers, LLMs, and AI agents. Built on Convex and Netlify.

View File

@@ -2,12 +2,26 @@
---
Type: page
Date: 2025-12-31
Date: 2026-01-01
---
All notable changes to this project.
![](https://img.shields.io/badge/License-MIT-yellow.svg)
## v2.2.2
Released December 31, 2025
**Homepage intro loading flash fix**
- Removed visible loading states from homepage intro content
- No more "Loading..." text flash when app loads (fixed Suspense fallback in main.tsx)
- No more bio text flash while home intro content loads (fixed conditional in Home.tsx)
- Home intro content now appears without any visible loading state or fallback
- Matches the loading pattern used by Post.tsx for docs pages (render nothing while loading)
Updated files: `src/main.tsx`, `src/pages/Home.tsx`, `changelog.md`, `content/pages/changelog-page.md`, `TASK.md`, `files.md`
## v2.2.1
Released December 31, 2025

View File

@@ -2,7 +2,7 @@
---
Type: page
Date: 2025-12-31
Date: 2026-01-01
---
You found the contact page. Nice

View File

@@ -2,7 +2,7 @@
---
Type: page
Date: 2025-12-31
Date: 2026-01-01
---
## Getting Started

View File

@@ -2,7 +2,7 @@
---
Type: page
Date: 2025-12-31
Date: 2026-01-01
---
Built with [Convex](https://convex.dev) for real-time sync and deployed on [Netlify](https://netlify.com). Read the [project on GitHub](https://github.com/waynesutton/markdown-site) to fork and deploy your own. View [real-time site stats](/stats).

View File

@@ -2,7 +2,7 @@
---
Type: page
Date: 2025-12-31
Date: 2026-01-01
---
An open-source publishing framework built for AI agents and developers to ship **[docs](/docs)**, or **[blogs](/blog)** or **[websites](/)**.

View File

@@ -2,7 +2,7 @@
---
Type: page
Date: 2025-12-31
Date: 2026-01-01
---
# Newsletter Demo Page

View File

@@ -2,7 +2,7 @@
---
Type: page
Date: 2025-12-31
Date: 2026-01-01
---
This markdown framework is open source and built to be extended. Here is what ships out of the box.

View File

@@ -491,7 +491,7 @@ export const siteConfig: SiteConfig = {
},
// Footer configuration
// Footer content is loaded from content/pages/footer.md (synced via npm run sync)
// Footer content is loaded from content/pages/footer.md (synced via npm run sync)
// Use showFooter: false in frontmatter to hide footer on specific posts/pages
footer: {
enabled: true, // Global toggle for footer

View File

@@ -18,21 +18,9 @@ const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL);
const AppWithWorkOS = lazy(() => import("./AppWithWorkOS"));
const App = lazy(() => import("./App"));
// Loading fallback
// Minimal loading fallback - no visible text to prevent flash
function LoadingFallback() {
return (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100vh",
fontFamily: "system-ui, sans-serif",
}}
>
Loading...
</div>
);
return <div style={{ minHeight: "100vh" }} />;
}
createRoot(document.getElementById("root")!).render(

View File

@@ -175,7 +175,8 @@ export default function Home() {
<h1 className="home-name">{siteConfig.name}</h1>
{/* Home intro from Convex page content (synced via npm run sync) */}
{homeIntro ? (
{/* Show nothing while loading (undefined), show content if found, fallback to bio only if page doesn't exist (null) */}
{homeIntro === undefined ? null : homeIntro ? (
<div
className="home-intro-content"
style={{
@@ -280,7 +281,7 @@ export default function Home() {
</ReactMarkdown>
</div>
) : (
// Fallback to siteConfig.bio while loading or if page doesn't exist
// Fallback to siteConfig.bio only if page doesn't exist (null)
<p className="home-bio">{siteConfig.bio}</p>
)}