Skip to content
This repository was archived by the owner on Mar 25, 2026. It is now read-only.

Commit 375bd89

Browse files
committed
docs: simplify readme
1 parent 2f35deb commit 375bd89

1 file changed

Lines changed: 1 addition & 376 deletions

File tree

README.md

Lines changed: 1 addition & 376 deletions
Original file line numberDiff line numberDiff line change
@@ -98,312 +98,6 @@ NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX
9898
NEXT_PUBLIC_PLAUSIBLE_DOMAIN=your-site.com
9999
```
100100

101-
### 3. Run Development Server
102-
103-
```bash
104-
pnpm dev
105-
```
106-
107-
Visit [http://localhost:3000](http://localhost:3000)
108-
109-
### 4. Build for Production
110-
111-
```bash
112-
pnpm build
113-
pnpm start
114-
```
115-
116-
## On-Demand Revalidation Setup
117-
118-
Rush CMS can automatically invalidate Next.js cache when content is updated.
119-
120-
### Step 1: Generate Revalidation Secret
121-
122-
```bash
123-
# Generate a secure random key
124-
openssl rand -hex 32
125-
```
126-
127-
Add to your `.env`:
128-
129-
```env
130-
REVALIDATE_SECRET=your-generated-secret-here
131-
```
132-
133-
### Step 2: Configure Webhook in Rush CMS
134-
135-
In your Rush CMS installation, configure the webhook:
136-
137-
**URL Format:**
138-
```
139-
https://your-nextjs-site.com/api/revalidate
140-
```
141-
142-
**Method:** `POST`
143-
144-
**Headers:**
145-
```
146-
Content-Type: application/json
147-
```
148-
149-
**Payload Example (Path Revalidation):**
150-
```json
151-
{
152-
"secret": "your-revalidation-secret",
153-
"path": "/blog/my-post-slug"
154-
}
155-
```
156-
157-
**Payload Example (Tag Revalidation):**
158-
```json
159-
{
160-
"secret": "your-revalidation-secret",
161-
"tag": "blog-posts"
162-
}
163-
```
164-
165-
### Step 3: Test Revalidation
166-
167-
Test manually with curl:
168-
169-
```bash
170-
curl -X POST https://your-site.com/api/revalidate \
171-
-H "Content-Type: application/json" \
172-
-d '{
173-
"secret": "your-secret",
174-
"path": "/"
175-
}'
176-
```
177-
178-
**Expected Response:**
179-
```json
180-
{
181-
"success": true,
182-
"message": "Revalidation triggered successfully",
183-
"revalidated": {
184-
"path": "/",
185-
"tag": null
186-
},
187-
"timestamp": "2025-11-12T10:30:00.000Z"
188-
}
189-
```
190-
191-
### Rush CMS Observer Implementation
192-
193-
Add this observer to your Rush CMS Laravel application:
194-
195-
```php
196-
<?php
197-
198-
namespace App\Observers;
199-
200-
use App\Models\Entry;
201-
use Illuminate\Support\Facades\Http;
202-
203-
class EntryObserver
204-
{
205-
public function updated(Entry $entry): void
206-
{
207-
$this->revalidateNextjs($entry);
208-
}
209-
210-
public function deleted(Entry $entry): void
211-
{
212-
$this->revalidateNextjs($entry);
213-
}
214-
215-
protected function revalidateNextjs(Entry $entry): void
216-
{
217-
$nextjsUrl = config('services.nextjs.url');
218-
$secret = config('services.nextjs.revalidate_secret');
219-
220-
if (!$nextjsUrl || !$secret) {
221-
return;
222-
}
223-
224-
// Determine path based on collection
225-
$path = match($entry->collection->slug) {
226-
'blog' => "/blog/{$entry->slug}",
227-
'pages' => "/{$entry->slug}",
228-
default => null,
229-
};
230-
231-
if ($path) {
232-
Http::post("{$nextjsUrl}/api/revalidate", [
233-
'secret' => $secret,
234-
'path' => $path,
235-
]);
236-
237-
// Also revalidate listing pages
238-
if ($entry->collection->slug === 'blog') {
239-
Http::post("{$nextjsUrl}/api/revalidate", [
240-
'secret' => $secret,
241-
'path' => '/blog',
242-
]);
243-
}
244-
}
245-
}
246-
}
247-
```
248-
249-
Register the observer in `AppServiceProvider`:
250-
251-
```php
252-
use App\Models\Entry;
253-
use App\Observers\EntryObserver;
254-
255-
public function boot(): void
256-
{
257-
Entry::observe(EntryObserver::class);
258-
}
259-
```
260-
261-
Add to `config/services.php`:
262-
263-
```php
264-
'nextjs' => [
265-
'url' => env('NEXTJS_URL', 'https://your-nextjs-site.com'),
266-
'revalidate_secret' => env('NEXTJS_REVALIDATE_SECRET'),
267-
],
268-
```
269-
270-
## Analytics Setup
271-
272-
### Google Analytics 4
273-
274-
1. Create a GA4 property in Google Analytics
275-
2. Get your Measurement ID (format: `G-XXXXXXXXXX`)
276-
3. Add to `.env`:
277-
278-
```env
279-
NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX
280-
```
281-
282-
### Plausible Analytics
283-
284-
1. Sign up at [plausible.io](https://plausible.io)
285-
2. Add your domain
286-
3. Add to `.env`:
287-
288-
```env
289-
NEXT_PUBLIC_PLAUSIBLE_DOMAIN=your-site.com
290-
```
291-
292-
### Custom Event Tracking
293-
294-
Use the analytics helpers in your code:
295-
296-
```typescript
297-
import { trackEvent, trackFormSubmit, trackSearch } from '@/lib/analytics'
298-
299-
// Track custom events
300-
trackEvent('button_click', { button_name: 'subscribe' })
301-
302-
// Track form submissions
303-
trackFormSubmit('contact_form', true)
304-
305-
// Track search queries
306-
trackSearch('next.js tutorial', 42)
307-
```
308-
309-
## Project Structure
310-
311-
```
312-
src/
313-
├── app/
314-
│ ├── api/
315-
│ │ └── revalidate/
316-
│ │ └── route.ts # Revalidation webhook endpoint
317-
│ ├── blog/
318-
│ │ ├── [slug]/
319-
│ │ │ ├── page.tsx # Blog post detail
320-
│ │ │ └── error.tsx # Blog post error boundary
321-
│ │ ├── page.tsx # Blog listing with search
322-
│ │ └── error.tsx # Blog error boundary
323-
│ ├── [slug]/
324-
│ │ └── page.tsx # Dynamic pages
325-
│ ├── contact/
326-
│ │ └── page.tsx # Contact form
327-
│ ├── error.tsx # Global error boundary
328-
│ ├── loading.tsx # Global loading state
329-
│ ├── not-found.tsx # 404 page
330-
│ ├── page.tsx # Homepage
331-
│ ├── layout.tsx # Root layout
332-
│ ├── globals.css # Global styles
333-
│ ├── sitemap.ts # Dynamic sitemap
334-
│ └── robots.ts # Robots.txt
335-
├── components/
336-
│ ├── analytics/
337-
│ │ └── analytics-script.tsx # Analytics integration
338-
│ ├── blog/
339-
│ │ └── blog-listing.tsx # Blog listing with search & pagination
340-
│ ├── breadcrumbs/
341-
│ │ └── breadcrumbs.tsx # Breadcrumb navigation
342-
│ ├── loading/
343-
│ │ ├── skeleton.tsx # Base skeleton loader
344-
│ │ ├── blog-post-skeleton.tsx # Blog post skeleton
345-
│ │ ├── card-skeleton.tsx # Card skeleton
346-
│ │ └── form-skeleton.tsx # Form skeleton
347-
│ ├── pagination/
348-
│ │ └── pagination.tsx # Pagination component
349-
│ ├── rush/
350-
│ │ ├── article.tsx # Blog post renderer
351-
│ │ ├── article-content.tsx # Article content with TOC
352-
│ │ ├── block-editor-renderer.tsx # Block editor
353-
│ │ ├── entry-renderer.tsx # Generic entry renderer
354-
│ │ └── form-builder.tsx # Dynamic forms
355-
│ ├── search/
356-
│ │ ├── blog-search.tsx # Generic search wrapper
357-
│ │ ├── search-input.tsx # Search input with debounce
358-
│ │ └── search-results.tsx # Search results display
359-
│ ├── share/
360-
│ │ └── share-buttons.tsx # Social media share buttons
361-
│ ├── structured-data/
362-
│ │ └── entry-schema.tsx # JSON-LD structured data
363-
│ ├── toc/
364-
│ │ └── table-of-contents.tsx # Table of contents
365-
│ ├── ui/
366-
│ │ ├── alert.tsx # Alert component
367-
│ │ ├── badge.tsx # Badge component
368-
│ │ ├── button.tsx # Button component
369-
│ │ ├── card.tsx # Card component
370-
│ │ ├── input.tsx # Input component
371-
│ │ ├── label.tsx # Label component
372-
│ │ ├── optimized-image.tsx # Optimized image wrapper
373-
│ │ ├── select.tsx # Select component
374-
│ │ └── textarea.tsx # Textarea component
375-
│ ├── blog-card.tsx # Blog card component
376-
│ └── navigation.tsx # Main navigation
377-
├── lib/
378-
│ ├── analytics.ts # Analytics helpers
379-
│ ├── config.ts # Centralized config
380-
│ ├── date.ts # Date formatting
381-
│ ├── logger.ts # Structured logging
382-
│ ├── metadata.ts # SEO metadata helpers
383-
│ ├── rush-cms.ts # API client
384-
│ ├── sanitize.ts # HTML sanitization
385-
│ └── utils.ts # Utility functions
386-
└── types/
387-
├── analytics.d.ts # Analytics types
388-
└── rush-cms.ts # TypeScript types
389-
```
390-
391-
## Available Scripts
392-
393-
```bash
394-
# Development
395-
pnpm dev # Start dev server (localhost:3000)
396-
pnpm type-check # Run TypeScript compiler check
397-
pnpm lint # Run ESLint
398-
399-
# Production
400-
pnpm build # Build for production
401-
pnpm start # Start production server
402-
403-
# Deployment
404-
pnpm deploy # Deploy to configured platform
405-
```
406-
407101
## Type Safety
408102

409103
This starter uses strict TypeScript with no `any` types:
@@ -428,8 +122,6 @@ See [DEPLOYMENT.md](./DEPLOYMENT.md) for comprehensive deployment guides for:
428122
- **Webhooks** - On-demand revalidation setup
429123
- **Troubleshooting** - Common deployment issues
430124

431-
### Quick Deploy
432-
433125
#### Vercel (Recommended)
434126

435127
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone)
@@ -452,71 +144,4 @@ pnpm i -g netlify-cli
452144

453145
# Deploy
454146
netlify deploy --prod
455-
```
456-
457-
## Troubleshooting
458-
459-
### Issue: API requests failing
460-
461-
**Check:**
462-
- `NEXT_PUBLIC_API_URL` is correct (no trailing slash)
463-
- `API_TOKEN` is valid (regenerate in Rush CMS if needed)
464-
- Rush CMS CORS settings allow your Next.js domain
465-
466-
### Issue: Images not loading
467-
468-
**Check:**
469-
- `NEXT_PUBLIC_S3_URL` matches your media storage URL
470-
- Add S3 domain to `next.config.js`:
471-
472-
```js
473-
images: {
474-
domains: ['your-bucket.s3.amazonaws.com']
475-
}
476-
```
477-
478-
### Issue: Revalidation not working
479-
480-
**Check:**
481-
- `REVALIDATE_SECRET` matches in both `.env` and Rush CMS webhook
482-
- Webhook URL is correct (https://your-site.com/api/revalidate)
483-
- Check Next.js logs for revalidation messages
484-
485-
### Issue: Analytics not tracking
486-
487-
**Check:**
488-
- Analytics only loads in production (`NODE_ENV=production`)
489-
- Environment variables use `NEXT_PUBLIC_` prefix
490-
- Check browser console for errors (ad blockers may interfere)
491-
492-
## Contributing
493-
494-
1. Fork the repository
495-
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
496-
3. Commit using conventional commits (`feat:`, `fix:`, `docs:`, etc.)
497-
4. Push to the branch (`git push origin feature/amazing-feature`)
498-
5. Open a Pull Request
499-
500-
## Code Style
501-
502-
This project follows strict code guidelines (see `CLAUDE.md`):
503-
504-
- Single quotes (`'`) not double quotes
505-
- Tabs (size 4) for indentation
506-
- No semicolons
507-
- Kebab-case file names (`blog-card.tsx`)
508-
- Mobile-first approach
509-
510-
## License
511-
512-
MIT
513-
514-
## Support
515-
516-
- **Rush CMS Documentation**: [https://docs.rushcms.com](https://docs.rushcms.com)
517-
- **Issues**: [GitHub Issues](https://github.com/your-org/rush-cms-nextjs-starter/issues)
518-
- **Discussions**: [GitHub Discussions](https://github.com/your-org/rush-cms-nextjs-starter/discussions)
519-
520-
---
521-
522-
Built with ❤️ using [Rush CMS](https://rushcms.com) and [Next.js](https://nextjs.org)
147+
```

0 commit comments

Comments
 (0)