-
Notifications
You must be signed in to change notification settings - Fork 264
Docs homepage redesign #1718
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Docs homepage redesign #1718
Changes from all commits
9cbcfb2
90d55fb
e167916
8a6dc65
a1d0c5a
61c5bca
d8443ce
bfa1713
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,126 @@ | ||||||||||||||||||||||||||||||||
# CLAUDE.md | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
## Repository Overview | ||||||||||||||||||||||||||||||||
This is the Optimism Documentation website repository that powers docs.optimism.io - the official technical documentation for the Optimism Collective, covering the OP Stack, Superchain, and interoperability features. | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
## Tech Stack | ||||||||||||||||||||||||||||||||
- **Framework**: Next.js 14.2.21 with React 18.2.0 | ||||||||||||||||||||||||||||||||
- **Documentation Engine**: Nextra 2.13.2 (docs theme) | ||||||||||||||||||||||||||||||||
- **Language**: TypeScript | ||||||||||||||||||||||||||||||||
- **Package Manager**: pnpm (required - do not use npm or yarn) | ||||||||||||||||||||||||||||||||
- **Content Format**: MDX (Markdown with React components) | ||||||||||||||||||||||||||||||||
- **Deployment**: Netlify | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
## Essential Commands | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
### Development | ||||||||||||||||||||||||||||||||
```bash | ||||||||||||||||||||||||||||||||
pnpm dev # Start development server at localhost:3001 | ||||||||||||||||||||||||||||||||
pnpm build # Create production build | ||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
### Quality Checks (Run before committing) | ||||||||||||||||||||||||||||||||
```bash | ||||||||||||||||||||||||||||||||
pnpm lint # Run all linting (ESLint + spellcheck + breadcrumbs + redirects + metadata) | ||||||||||||||||||||||||||||||||
pnpm fix # Auto-fix all fixable issues (runs on pre-push automatically) | ||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
### Individual Linting Commands | ||||||||||||||||||||||||||||||||
```bash | ||||||||||||||||||||||||||||||||
pnpm spellcheck:lint # Check spelling | ||||||||||||||||||||||||||||||||
pnpm spellcheck:fix # Add words to dictionary (words.txt) | ||||||||||||||||||||||||||||||||
pnpm lint:eslint # Run ESLint | ||||||||||||||||||||||||||||||||
pnpm lint:breadcrumbs # Validate breadcrumb structure | ||||||||||||||||||||||||||||||||
pnpm lint:redirects # Check redirect configuration | ||||||||||||||||||||||||||||||||
pnpm lint:metadata # Validate page metadata | ||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||
Comment on lines
+31
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainListed per-tool lint scripts don’t exist The docs advertise Option A (fix docs): - pnpm lint:eslint # Run ESLint
- pnpm lint:breadcrumbs # Validate breadcrumb structure
- pnpm lint:redirects # Check redirect configuration
- pnpm lint:metadata # Validate page metadata
+ pnpm lint # ESLint + spellcheck + breadcrumbs + redirects + metadata
+ pnpm check-breadcrumbs # Validate breadcrumb structure
+ pnpm check-redirects # Check redirect configuration
+ pnpm validate-metadata # Validate page metadata Option B (add scripts to package.json): "scripts": {
+ "lint:eslint": "eslint . --ext mdx",
+ "lint:breadcrumbs": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/breadcrumbs.ts",
+ "lint:redirects": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/redirects.ts",
+ "lint:metadata": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/metadata-validator.ts", Check which path you prefer and keep docs aligned: 🏁 Script executed: #!/bin/bash
# Show available scripts
cat package.json | jq '.scripts' Length of output: 1376 Sync CLI docs with package.json scripts The commands listed in CLAUDE.md (lines 31–38) reference scripts that don’t exist in package.json. Choose one of the following to restore alignment: Option A – Update CLAUDE.md: --- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -31,7 +31,11 @@
pnpm spellcheck:lint # Check spelling
pnpm spellcheck:fix # Add words to dictionary (words.txt)
- pnpm lint:eslint # Run ESLint
- pnpm lint:breadcrumbs # Validate breadcrumb structure
- pnpm lint:redirects # Check redirect configuration
- pnpm lint:metadata # Validate page metadata
+ pnpm lint # Run ESLint, spellcheck, breadcrumbs, redirects, metadata, link-checker
+ pnpm check-breadcrumbs # Validate breadcrumb structure
+ pnpm check-redirects # Check redirect configuration
+ pnpm validate-metadata # Validate page metadata
+ pnpm link-checker # Check for broken links Option B – Add missing aliases to package.json scripts: --- a/package.json
+++ b/package.json
@@ "scripts": {
+ "lint:eslint": "eslint . --ext mdx --max-warnings 0",
+ "lint:breadcrumbs": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/breadcrumbs.ts",
+ "lint:redirects": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/redirects.ts",
+ "lint:metadata": "CHANGED_FILES=$(git diff --name-only --cached) NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/metadata-validator.ts", Let me know which approach you prefer so the docs and scripts stay in sync. 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
## Architecture & Structure | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
### Content Organization | ||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||
pages/ # All documentation content (MDX files) | ||||||||||||||||||||||||||||||||
├── app-developers/ # Application developer guides | ||||||||||||||||||||||||||||||||
├── operators/ # Node & chain operator documentation | ||||||||||||||||||||||||||||||||
├── stack/ # OP Stack protocol documentation | ||||||||||||||||||||||||||||||||
├── superchain/ # Superchain network documentation | ||||||||||||||||||||||||||||||||
├── interop/ # Interoperability documentation | ||||||||||||||||||||||||||||||||
└── connect/ # Contributing guides and resources | ||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
Comment on lines
+43
to
+52
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a language to the fenced code block (markdownlint MD040) Specify a language (e.g., text) for the directory tree block to satisfy linters and improve readability. -```
+```text
pages/ # All documentation content (MDX files)
├── app-developers/ # Application developer guides
├── operators/ # Node & chain operator documentation
├── stack/ # OP Stack protocol documentation
├── superchain/ # Superchain network documentation
├── interop/ # Interoperability documentation
└── connect/ # Contributing guides and resources
In CLAUDE.md around lines 43 to 52, the fenced code block showing the directory
|
||||||||||||||||||||||||||||||||
### Key Directories | ||||||||||||||||||||||||||||||||
- `components/`: Reusable React components for documentation | ||||||||||||||||||||||||||||||||
- `public/`: Static assets, images, and tutorial files | ||||||||||||||||||||||||||||||||
- `utils/`: Utility scripts for linting, validation, and build processes | ||||||||||||||||||||||||||||||||
- `providers/`: React context providers for global state | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
## Important Patterns | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
### MDX Page Structure | ||||||||||||||||||||||||||||||||
All documentation pages use MDX format with frontmatter metadata: | ||||||||||||||||||||||||||||||||
```mdx | ||||||||||||||||||||||||||||||||
--- | ||||||||||||||||||||||||||||||||
title: Page Title | ||||||||||||||||||||||||||||||||
lang: en-US | ||||||||||||||||||||||||||||||||
description: Page description for SEO | ||||||||||||||||||||||||||||||||
--- | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
import { ComponentName } from '@/components/ComponentName' | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
# Content here... | ||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
### Component Imports | ||||||||||||||||||||||||||||||||
Use the configured path alias for component imports: | ||||||||||||||||||||||||||||||||
```typescript | ||||||||||||||||||||||||||||||||
import { ComponentName } from '@/components/ComponentName' | ||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
### Adding New Documentation | ||||||||||||||||||||||||||||||||
1. Create MDX file in appropriate `pages/` subdirectory | ||||||||||||||||||||||||||||||||
2. Include required frontmatter (title, lang, description) | ||||||||||||||||||||||||||||||||
3. Run `pnpm lint` to validate metadata and content | ||||||||||||||||||||||||||||||||
4. Use existing components from `components/` directory when possible | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
### Spell Checking | ||||||||||||||||||||||||||||||||
- Custom dictionary maintained in `words.txt` | ||||||||||||||||||||||||||||||||
- Add technical terms using `pnpm spellcheck:fix` | ||||||||||||||||||||||||||||||||
- Spell checking runs automatically in the lint pipeline | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
## Git Workflow | ||||||||||||||||||||||||||||||||
- **Pre-push hook**: Automatically runs `pnpm fix` via Husky | ||||||||||||||||||||||||||||||||
- **Auto-commit**: Fixes are automatically committed if changes are made | ||||||||||||||||||||||||||||||||
- **No pre-commit hooks**: Only validation on push | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
## Special Features | ||||||||||||||||||||||||||||||||
- **Kapa.ai Widget**: AI assistant integrated for documentation queries | ||||||||||||||||||||||||||||||||
- **Algolia Search**: Full-text search across documentation | ||||||||||||||||||||||||||||||||
- **Feelback**: User feedback collection system | ||||||||||||||||||||||||||||||||
- **Growth Book**: A/B testing framework for feature experiments | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
## Common Tasks | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
### Adding a New Page | ||||||||||||||||||||||||||||||||
1. Create `.mdx` file in appropriate `pages/` directory | ||||||||||||||||||||||||||||||||
2. Add frontmatter with title, lang, and description | ||||||||||||||||||||||||||||||||
3. Write content using Markdown and import React components as needed | ||||||||||||||||||||||||||||||||
4. Run `pnpm dev` to preview | ||||||||||||||||||||||||||||||||
5. Run `pnpm lint` before committing | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
### Updating Components | ||||||||||||||||||||||||||||||||
- Components are in `components/` directory | ||||||||||||||||||||||||||||||||
- Follow existing patterns and TypeScript types | ||||||||||||||||||||||||||||||||
- Test component changes across multiple pages that use them | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
### Working with Images | ||||||||||||||||||||||||||||||||
- Place images in `public/img/` directory | ||||||||||||||||||||||||||||||||
- Reference using `/img/filename.ext` in MDX files | ||||||||||||||||||||||||||||||||
- Optimize images before adding to repository | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
## Notes | ||||||||||||||||||||||||||||||||
- The repository uses automated quality checks - always run `pnpm lint` before pushing | ||||||||||||||||||||||||||||||||
- Netlify handles deployment automatically on merge to main | ||||||||||||||||||||||||||||||||
- TypeScript is configured with relaxed strict mode - follow existing patterns | ||||||||||||||||||||||||||||||||
- MDX allows mixing Markdown with React components - leverage this for interactive content |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,55 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import React, { useState, useEffect } from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { useRouter } from 'next/router'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const LoadingBar = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const [loading, setLoading] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const [progress, setProgress] = useState(0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const router = useRouter(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
useEffect(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let progressTimer: NodeJS.Timeout; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let finishTimer: NodeJS.Timeout; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+10
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Timer types may be incompatible in the browser Using NodeJS.Timeout can cause TS type errors in browser contexts. Prefer ReturnType for cross-env compatibility. - let progressTimer: NodeJS.Timeout;
- let finishTimer: NodeJS.Timeout;
+ let progressTimer: ReturnType<typeof setTimeout> | null = null;
+ let finishTimer: ReturnType<typeof setTimeout> | null = null; 🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const handleStart = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setLoading(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setProgress(0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
progressTimer = setTimeout(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setProgress(70); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, 200); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const handleComplete = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setProgress(100); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
finishTimer = setTimeout(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setLoading(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setProgress(0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, 300); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+22
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Race condition: clear the pending progress timer on completion If a route completes before the 200ms timer fires, progress can jump back to 70% after completion. Clear the progress timer in handleComplete to avoid flicker. - const handleComplete = () => {
- setProgress(100);
- finishTimer = setTimeout(() => {
- setLoading(false);
- setProgress(0);
- }, 300);
- };
+ const handleComplete = () => {
+ if (progressTimer) {
+ clearTimeout(progressTimer);
+ progressTimer = null;
+ }
+ setProgress(100);
+ finishTimer = setTimeout(() => {
+ setLoading(false);
+ setProgress(0);
+ finishTimer = null;
+ }, 300);
+ }; Also consider cancelling any pending finishTimer when a new navigation starts: const handleStart = () => {
setLoading(true);
setProgress(0);
-
+ if (finishTimer) {
+ clearTimeout(finishTimer);
+ finishTimer = null;
+ } 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
router.events.on('routeChangeStart', handleStart); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
router.events.on('routeChangeComplete', handleComplete); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
router.events.on('routeChangeError', handleComplete); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
router.events.off('routeChangeStart', handleStart); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
router.events.off('routeChangeComplete', handleComplete); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
router.events.off('routeChangeError', handleComplete); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
clearTimeout(progressTimer); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
clearTimeout(finishTimer); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, [router]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!loading) return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="nx-fixed nx-top-0 nx-left-0 nx-right-0 nx-z-50 nx-h-1 nx-bg-transparent"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="nx-h-full nx-bg-primary-500 nx-transition-all nx-duration-300 nx-ease-out" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
style={{ width: `${progress}%` }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export default LoadingBar; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect dev server port
The script "dev" in package.json is
next dev
without a-p
flag, which defaults to port 3000, not 3001. Update the docs or the script for consistency.Apply one of:
or change package.json script:
📝 Committable suggestion
🤖 Prompt for AI Agents