mirror of
https://github.com/waynesutton/markdown-site.git
synced 2026-01-12 04:09:14 +00:00
feat: add featured section, logo gallery, Firecrawl import, and API export
Featured Section - Frontmatter-controlled featured items with featured: true and featuredOrder - Card view with excerpts and list/card toggle button - View preference saved to localStorage - New Convex queries for featured posts and pages with by_featured index Logo Gallery - Continuous marquee scroll with clickable logos - CSS animation, grayscale with color on hover - Configurable speed, position, and title - 5 sample logos included Firecrawl Content Importer - npm run import <url> scrapes external URLs to markdown drafts - Creates local files in content/blog/ with frontmatter - Then sync to dev or prod (no separate import:prod command) API Enhancements - New /api/export endpoint for batch content fetching - AI plugin discovery at /.well-known/ai-plugin.json - OpenAPI 3.0 spec at /openapi.yaml - Enhanced llms.txt documentation Documentation - AGENTS.md with codebase instructions for AI agents - Updated all sync vs deploy tables to include import workflow - Renamed content/pages/changelog.md to changelog-page.md Technical - New components: FeaturedCards.tsx, LogoMarquee.tsx - New script: scripts/import-url.ts - New dependency: @mendable/firecrawl-js - Schema updates with featured, featuredOrder, excerpt fields
This commit is contained in:
165
README.md
165
README.md
@@ -13,6 +13,8 @@ A minimalist markdown site built with React, Convex, and Vite. Optimized for SEO
|
||||
- Fully responsive design
|
||||
- Real-time analytics at `/stats`
|
||||
- Full text search with Command+K shortcut
|
||||
- Featured section with list/card view toggle
|
||||
- Logo gallery with continuous marquee scroll
|
||||
|
||||
### SEO and Discovery
|
||||
|
||||
@@ -27,9 +29,18 @@ A minimalist markdown site built with React, Convex, and Vite. Optimized for SEO
|
||||
|
||||
- `/api/posts` - JSON list of all posts for agents
|
||||
- `/api/post?slug=xxx` - Single post JSON or markdown
|
||||
- `/api/export` - Batch export all posts with full content
|
||||
- `/rss-full.xml` - Full content RSS for LLM ingestion
|
||||
- `/.well-known/ai-plugin.json` - AI plugin manifest
|
||||
- `/openapi.yaml` - OpenAPI 3.0 specification
|
||||
- Copy Page dropdown for sharing to ChatGPT, Claude
|
||||
|
||||
### Content Import
|
||||
|
||||
- Import external URLs as markdown posts using Firecrawl
|
||||
- Run `npm run import <url>` to scrape and create draft posts locally
|
||||
- Then sync to dev or prod with `npm run sync` or `npm run sync:prod`
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
@@ -92,6 +103,7 @@ published: true
|
||||
tags: ["tag1", "tag2"]
|
||||
readTime: "5 min read"
|
||||
image: "/images/my-header.png"
|
||||
excerpt: "Short text for featured cards"
|
||||
---
|
||||
|
||||
Your markdown content here...
|
||||
@@ -132,6 +144,85 @@ const siteConfig = {
|
||||
|
||||
Replace `public/images/logo.svg` with your own logo file.
|
||||
|
||||
## Featured Section
|
||||
|
||||
Posts and pages with `featured: true` in frontmatter appear in the featured section.
|
||||
|
||||
### Add to Featured
|
||||
|
||||
Add these fields to any post or page frontmatter:
|
||||
|
||||
```yaml
|
||||
featured: true
|
||||
featuredOrder: 1
|
||||
excerpt: "A short description for the card view."
|
||||
```
|
||||
|
||||
Then run `npm run sync`. No redeploy needed.
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `featured` | Set `true` to show in featured section |
|
||||
| `featuredOrder` | Order in featured section (lower = first) |
|
||||
| `excerpt` | Short description for card view |
|
||||
|
||||
### Display Modes
|
||||
|
||||
The featured section supports two display modes:
|
||||
|
||||
- **List view** (default): Bullet list of links
|
||||
- **Card view**: Grid of cards with title and excerpt
|
||||
|
||||
Users can toggle between views. To change the default:
|
||||
|
||||
```typescript
|
||||
const siteConfig = {
|
||||
featuredViewMode: "cards", // 'list' or 'cards'
|
||||
showViewToggle: true, // Allow users to switch views
|
||||
};
|
||||
```
|
||||
|
||||
## Logo Gallery
|
||||
|
||||
The homepage includes a scrolling logo gallery with sample logos. Configure in `siteConfig`:
|
||||
|
||||
### Disable the gallery
|
||||
|
||||
```typescript
|
||||
logoGallery: {
|
||||
enabled: false,
|
||||
// ...
|
||||
},
|
||||
```
|
||||
|
||||
### Replace with your own logos
|
||||
|
||||
1. Add logo images to `public/images/logos/` (SVG recommended)
|
||||
2. Update the images array with logos and links:
|
||||
|
||||
```typescript
|
||||
logoGallery: {
|
||||
enabled: true,
|
||||
images: [
|
||||
{ src: "/images/logos/your-logo-1.svg", href: "https://example.com" },
|
||||
{ src: "/images/logos/your-logo-2.svg", href: "https://anothersite.com" },
|
||||
],
|
||||
position: "above-footer", // or "below-featured"
|
||||
speed: 30, // Seconds for one scroll cycle
|
||||
title: "Trusted by", // Set to undefined to hide
|
||||
},
|
||||
```
|
||||
|
||||
Each logo object supports:
|
||||
- `src`: Path to the logo image (required)
|
||||
- `href`: URL to link to when clicked (optional)
|
||||
|
||||
### Remove sample logos
|
||||
|
||||
Delete sample files from `public/images/logos/` and replace the images array with your own logos, or set `enabled: false` to hide the gallery entirely.
|
||||
|
||||
The gallery uses CSS animations for smooth infinite scrolling. Logos appear grayscale and colorize on hover.
|
||||
|
||||
### Favicon
|
||||
|
||||
Replace `public/favicon.svg` with your own icon. The default is a rounded square with the letter "m". Edit the SVG to change the letter or style.
|
||||
@@ -244,15 +335,16 @@ markdown-site/
|
||||
|
||||
## Scripts Reference
|
||||
|
||||
| Script | Description |
|
||||
| --------------------- | -------------------------------------------- |
|
||||
| `npm run dev` | Start Vite dev server |
|
||||
| `npm run dev:convex` | Start Convex dev backend |
|
||||
| `npm run sync` | Sync posts to dev deployment |
|
||||
| `npm run sync:prod` | Sync posts to production deployment |
|
||||
| `npm run build` | Build for production |
|
||||
| `npm run deploy` | Sync + build (for manual deploys) |
|
||||
| `npm run deploy:prod` | Deploy Convex functions + sync to production |
|
||||
| Script | Description |
|
||||
| --------------------- | -------------------------------------------------- |
|
||||
| `npm run dev` | Start Vite dev server |
|
||||
| `npm run dev:convex` | Start Convex dev backend |
|
||||
| `npm run sync` | Sync posts to dev deployment |
|
||||
| `npm run sync:prod` | Sync posts to production deployment |
|
||||
| `npm run import` | Import URL as local markdown draft (then sync) |
|
||||
| `npm run build` | Build for production |
|
||||
| `npm run deploy` | Sync + build (for manual deploys) |
|
||||
| `npm run deploy:prod` | Deploy Convex functions + sync to production |
|
||||
|
||||
## Tech Stack
|
||||
|
||||
@@ -301,16 +393,51 @@ How it works:
|
||||
|
||||
## API Endpoints
|
||||
|
||||
| Endpoint | Description |
|
||||
| ------------------------------ | ------------------------------- |
|
||||
| `/stats` | Real-time site analytics |
|
||||
| `/rss.xml` | RSS feed with post descriptions |
|
||||
| `/rss-full.xml` | RSS feed with full post content |
|
||||
| `/sitemap.xml` | Dynamic XML sitemap |
|
||||
| `/api/posts` | JSON list of all posts |
|
||||
| `/api/post?slug=xxx` | Single post as JSON |
|
||||
| `/api/post?slug=xxx&format=md` | Single post as markdown |
|
||||
| `/meta/post?slug=xxx` | Open Graph HTML for crawlers |
|
||||
| Endpoint | Description |
|
||||
| ------------------------------ | ------------------------------------ |
|
||||
| `/stats` | Real-time site analytics |
|
||||
| `/rss.xml` | RSS feed with post descriptions |
|
||||
| `/rss-full.xml` | RSS feed with full post content |
|
||||
| `/sitemap.xml` | Dynamic XML sitemap |
|
||||
| `/api/posts` | JSON list of all posts |
|
||||
| `/api/post?slug=xxx` | Single post as JSON |
|
||||
| `/api/post?slug=xxx&format=md` | Single post as markdown |
|
||||
| `/api/export` | Batch export all posts with content |
|
||||
| `/meta/post?slug=xxx` | Open Graph HTML for crawlers |
|
||||
| `/.well-known/ai-plugin.json` | AI plugin manifest |
|
||||
| `/openapi.yaml` | OpenAPI 3.0 specification |
|
||||
| `/llms.txt` | AI agent discovery |
|
||||
|
||||
## Import External Content
|
||||
|
||||
Use Firecrawl to import articles from external URLs as markdown posts:
|
||||
|
||||
```bash
|
||||
npm run import https://example.com/article
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
1. Scrape the URL using Firecrawl API
|
||||
2. Convert to clean markdown
|
||||
3. Create a draft post in `content/blog/` locally
|
||||
4. Add frontmatter with title, description, and today's date
|
||||
|
||||
**Setup:**
|
||||
|
||||
1. Get an API key from [firecrawl.dev](https://firecrawl.dev)
|
||||
2. Add to `.env.local`:
|
||||
|
||||
```
|
||||
FIRECRAWL_API_KEY=fc-your-api-key
|
||||
```
|
||||
|
||||
**Why no `npm run import:prod`?** The import command only creates local markdown files. It does not interact with Convex. After importing, sync to your target environment:
|
||||
|
||||
- `npm run sync` for development
|
||||
- `npm run sync:prod` for production
|
||||
|
||||
Imported posts are created as drafts (`published: false`). Review, edit, set `published: true`, then sync.
|
||||
|
||||
## How Blog Post Slugs Work
|
||||
|
||||
|
||||
Reference in New Issue
Block a user