A modern personal website built with Next.js, React, TypeScript, and Tailwind CSS.
- Modern, responsive design with Tailwind CSS
- Server-side rendering with Next.js App Router
- Dynamic content from Supabase database
- Optimized for performance with Next.js image optimization
- Mobile-friendly navigation with animated menu
- Framework: Next.js 15.2.4 with App Router
- Language: TypeScript
- Styling: Tailwind CSS
- Database: Supabase
- Deployment: Vercel
- UI Components: Radix UI
- Analytics: Vercel Analytics
- Node.js 20.11.1 or later
- pnpm (recommended) or npm/yarn
- Supabase account (for database functionality)
-
Clone the repository:
git clone https://github.com/yourusername/doug-is.git cd doug-is -
Install dependencies:
pnpm install
-
Create a
.env.localfile in the root directory with the following variables:NEXT_PUBLIC_SUPABASE_URL=your_supabase_url NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key -
Start the development server:
chmod +x ./start.sh ./start.sh
-
Open http://localhost:3000 in your browser to see the result.
/src/app: Next.js App Router pages and API routes/src/components: Reusable UI components/src/lib: Utility functions and services/src/content: Static content for the website/supabase: Supabase configuration and migrations/scripts: Utility scripts for development and database management
The project uses a simplified single-file migration approach for Supabase. The complete schema is defined in /supabase/migrations/20000000000000_schema_setup.sql.
If you need to reset your database and apply the migration:
-
Reset your database (WARNING: this will delete all data):
-- Run this in Supabase SQL Editor DROP SCHEMA public CASCADE; CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO postgres; GRANT ALL ON SCHEMA public TO public;
-
Apply the migration:
# Make sure you've logged in and linked your project first supabase login supabase link --project-ref tzffjzocrazemvtgqavg # Push migrations supabase db push
The schema includes these main tables:
posts: Blog posts with title, content, and publishing statuscontact_messages: Contact form submissionsuser_roles: User role assignments for access control
This project implements comprehensive metadata and social media sharing functionality across all pages using Next.js 15 Metadata API.
- Complete Coverage: All page types have proper OpenGraph and Twitter Card metadata
- Social Platform Support: Optimized for Twitter/X, LinkedIn, Facebook, Discord, Slack, and messaging apps
- Dynamic Generation: Content-driven metadata for blog posts and projects
- SEO Optimization: Proper meta descriptions and canonical URLs for search engines
- Brand Consistency: Unified "doug.is" branding across all social sharing
- Security: Admin pages protected with noindex metadata
Metadata Patterns:
- Section pages: "doug.is / SectionName"
- Project pages: "ProjectName | Building | doug.is"
- Blog posts: "PostTitle | Thinking | doug.is"
Social Sharing Images:
- Dimensions: 1200x630px for optimal platform compatibility
- Location:
/public/images/directory - Branding: Consistent doug.is visual identity
Comprehensive Guide: .cursor/rules/metadata.mdc
- Implementation patterns and examples
- Social sharing image workflow
- Testing framework and validation
- Troubleshooting and debug tools
Quick Reference: METADATA_MAINTENANCE_CHECKLIST.md
- Step-by-step checklists for adding new pages
- Monthly and quarterly maintenance tasks
- Emergency troubleshooting procedures
# Run metadata-specific tests
npm test -- --testNamePattern="Metadata"
# Validate metadata structure
npm test src/components/__tests__/MetadataValidation.test.tsx- Twitter: https://cards-dev.twitter.com/validator
- Facebook: https://developers.facebook.com/tools/debug/
- LinkedIn: https://www.linkedin.com/post-inspector/
The project is deployed on Vercel. Any push to the main branch will trigger a new deployment.
Make sure to set the following environment variables in your Vercel project:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEY
This project includes a comprehensive testing setup with Jest, React Testing Library, and Playwright for different types of testing.
- Unit/Component Tests: Jest with React Testing Library
- Test Environment: jsdom for browser-like testing
- Coverage: Enabled with detailed reporting
- Mocking: Custom utilities for Supabase and Next.js features
- E2E Testing: Playwright (available but needs configuration)
# Run all tests once
pnpm test
# Run tests in watch mode (recommended for development)
pnpm test:watch
# Run tests with coverage report
pnpm test:coverageTests are located in __tests__ directories alongside the components they test:
src/
├── components/
│ ├── __tests__/
│ │ └── StatusMessage.test.tsx
│ └── admin/
│ └── __tests__/
│ ├── LoginForm.test.tsx
│ └── PostsTable.test.tsx
The project uses custom test utilities located in src/lib/test-utils.tsx that provide:
- Supabase Mocking: Pre-configured mocks for Supabase client operations
- Next.js Mocking: Mocks for navigation, routing, and images
- Custom Render: Enhanced render function with provider setup
Example test:
import { render, screen } from '@/lib/test-utils'
import { setupSupabaseMock } from '@/lib/test-utils'
import MyComponent from '../MyComponent'
describe('MyComponent', () => {
beforeEach(() => {
setupSupabaseMock()
})
it('renders correctly', () => {
render(<MyComponent />)
expect(screen.getByText('Expected text')).toBeInTheDocument()
})
})- Jest Config:
jest.config.ts- Configured for Next.js with path mapping - Setup File:
jest.setup.ts- Global test setup and mocks - Coverage: Collects from all
src/**/*.{ts,tsx}files except API routes and type definitions
After running pnpm test:coverage, coverage reports are generated in the coverage/ directory:
coverage/lcov-report/index.html- Detailed HTML coverage reportcoverage/lcov.info- LCOV format for CI/CD integration
- Create a
__tests__directory next to your component - Name your test file
ComponentName.test.tsx - Import testing utilities from
@/lib/test-utils - Use
setupSupabaseMock()for components that interact with Supabase - Follow the existing test patterns for consistency
Playwright is installed but not yet configured. To set up E2E testing:
- Create
playwright.config.tsin the project root - Add E2E test scripts to
package.json - Create
tests/directory for E2E test files
First, run the development server:
chmod +x start.sh
./start.shOpen http://localhost:3000 with your browser to see the result.
This project is licensed under the MIT License - see the LICENSE file for details.