@seo-console/package 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +239 -45
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SEO Console Package
|
|
2
2
|
|
|
3
|
-
A production-ready SEO validation and management system for Next.js applications.
|
|
3
|
+
A production-ready SEO validation and management system for Next.js applications. This package provides a complete admin interface for managing SEO metadata, accessible through a new tab in your admin section.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -8,68 +8,256 @@ A production-ready SEO validation and management system for Next.js applications
|
|
|
8
8
|
npm install @seo-console/package
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Setup Guide
|
|
12
12
|
|
|
13
|
-
### 1
|
|
13
|
+
### Step 1: Configure Storage (Optional)
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
2. Run the database migrations from `supabase/migrations/`:
|
|
17
|
-
- `001_initial_schema.sql` - User profiles
|
|
18
|
-
- `002_seo_records_schema.sql` - SEO records table
|
|
15
|
+
The package uses **file storage by default** (no database required). SEO records are stored in `seo-records.json`.
|
|
19
16
|
|
|
20
|
-
|
|
17
|
+
To customize the storage location, add to your `.env.local`:
|
|
21
18
|
|
|
22
|
-
|
|
19
|
+
```env
|
|
20
|
+
SEO_CONSOLE_STORAGE_PATH=./data/seo-records.json
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Optional:** If you prefer Supabase, set these environment variables:
|
|
23
24
|
|
|
24
25
|
```env
|
|
25
26
|
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
|
|
26
27
|
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
|
|
27
28
|
```
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
The package will automatically detect and use Supabase if these are set.
|
|
31
|
+
|
|
32
|
+
### Step 2: Create API Routes
|
|
33
|
+
|
|
34
|
+
Create the following API route in your Next.js app:
|
|
30
35
|
|
|
31
|
-
|
|
36
|
+
**`app/api/seo-records/route.ts`:**
|
|
32
37
|
|
|
33
38
|
```typescript
|
|
34
|
-
|
|
35
|
-
import {
|
|
39
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
40
|
+
import {
|
|
41
|
+
getSEORecords,
|
|
42
|
+
getSEORecordByRoute,
|
|
43
|
+
createSEORecord,
|
|
44
|
+
updateSEORecord,
|
|
45
|
+
deleteSEORecord
|
|
46
|
+
} from "@seo-console/package/server";
|
|
47
|
+
|
|
48
|
+
// GET - Fetch all SEO records
|
|
49
|
+
export async function GET() {
|
|
50
|
+
try {
|
|
51
|
+
const result = await getSEORecords();
|
|
52
|
+
if (!result.success) {
|
|
53
|
+
return NextResponse.json({ error: result.error?.message }, { status: 500 });
|
|
54
|
+
}
|
|
55
|
+
return NextResponse.json({ data: result.data || [] });
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return NextResponse.json(
|
|
58
|
+
{ error: error instanceof Error ? error.message : "Failed to fetch records" },
|
|
59
|
+
{ status: 500 }
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
36
63
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
64
|
+
// POST - Create a new SEO record
|
|
65
|
+
export async function POST(request: NextRequest) {
|
|
66
|
+
try {
|
|
67
|
+
const body = await request.json();
|
|
68
|
+
const result = await createSEORecord(body);
|
|
69
|
+
if (!result.success) {
|
|
70
|
+
return NextResponse.json({ error: result.error?.message }, { status: 500 });
|
|
71
|
+
}
|
|
72
|
+
return NextResponse.json({ data: result.data });
|
|
73
|
+
} catch (error) {
|
|
74
|
+
return NextResponse.json(
|
|
75
|
+
{ error: error instanceof Error ? error.message : "Failed to create record" },
|
|
76
|
+
{ status: 500 }
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// PUT - Update an existing SEO record
|
|
82
|
+
export async function PUT(request: NextRequest) {
|
|
83
|
+
try {
|
|
84
|
+
const body = await request.json();
|
|
85
|
+
const result = await updateSEORecord(body);
|
|
86
|
+
if (!result.success) {
|
|
87
|
+
return NextResponse.json({ error: result.error?.message }, { status: 500 });
|
|
88
|
+
}
|
|
89
|
+
return NextResponse.json({ data: result.data });
|
|
90
|
+
} catch (error) {
|
|
91
|
+
return NextResponse.json(
|
|
92
|
+
{ error: error instanceof Error ? error.message : "Failed to update record" },
|
|
93
|
+
{ status: 500 }
|
|
94
|
+
);
|
|
95
|
+
}
|
|
42
96
|
}
|
|
97
|
+
|
|
98
|
+
// DELETE - Delete an SEO record
|
|
99
|
+
export async function DELETE(request: NextRequest) {
|
|
100
|
+
try {
|
|
101
|
+
const { searchParams } = new URL(request.url);
|
|
102
|
+
const id = searchParams.get("id");
|
|
103
|
+
if (!id) {
|
|
104
|
+
return NextResponse.json({ error: "ID is required" }, { status: 400 });
|
|
105
|
+
}
|
|
106
|
+
const result = await deleteSEORecord(id);
|
|
107
|
+
if (!result.success) {
|
|
108
|
+
return NextResponse.json({ error: result.error?.message }, { status: 500 });
|
|
109
|
+
}
|
|
110
|
+
return NextResponse.json({ success: true });
|
|
111
|
+
} catch (error) {
|
|
112
|
+
return NextResponse.json(
|
|
113
|
+
{ error: error instanceof Error ? error.message : "Failed to delete record" },
|
|
114
|
+
{ status: 500 }
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Step 3: Add Admin Pages
|
|
121
|
+
|
|
122
|
+
Create the admin SEO section in your Next.js app. This will be accessible as a new tab in your admin area.
|
|
123
|
+
|
|
124
|
+
**Create the directory structure:**
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
app/admin/seo/
|
|
128
|
+
├── page.tsx (Main dashboard)
|
|
129
|
+
├── editor/
|
|
130
|
+
│ └── page.tsx (SEO record editor)
|
|
131
|
+
├── reports/
|
|
132
|
+
│ └── page.tsx (Reports & analytics)
|
|
133
|
+
├── search/
|
|
134
|
+
│ └── page.tsx (Search & validation)
|
|
135
|
+
└── settings/
|
|
136
|
+
└── page.tsx (Settings)
|
|
43
137
|
```
|
|
44
138
|
|
|
45
|
-
|
|
139
|
+
**`app/admin/seo/page.tsx` (Main Dashboard):**
|
|
46
140
|
|
|
47
141
|
```typescript
|
|
48
|
-
// app/admin/seo/page.tsx
|
|
49
142
|
"use client";
|
|
50
143
|
|
|
51
|
-
import {
|
|
52
|
-
import {
|
|
144
|
+
import { useState, useEffect } from "react";
|
|
145
|
+
import { useRouter } from "next/navigation";
|
|
146
|
+
import type { SEORecord } from "@seo-console/package";
|
|
53
147
|
|
|
54
148
|
export default function SEOAdminPage() {
|
|
149
|
+
const router = useRouter();
|
|
150
|
+
const [records, setRecords] = useState<SEORecord[]>([]);
|
|
151
|
+
const [loading, setLoading] = useState(true);
|
|
152
|
+
|
|
153
|
+
useEffect(() => {
|
|
154
|
+
fetch("/api/seo-records")
|
|
155
|
+
.then((res) => res.json())
|
|
156
|
+
.then((data) => {
|
|
157
|
+
setRecords(data.data || []);
|
|
158
|
+
setLoading(false);
|
|
159
|
+
})
|
|
160
|
+
.catch(() => setLoading(false));
|
|
161
|
+
}, []);
|
|
162
|
+
|
|
55
163
|
return (
|
|
56
164
|
<div>
|
|
57
165
|
<h1>SEO Management</h1>
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
166
|
+
<nav>
|
|
167
|
+
<a href="/admin/seo">Dashboard</a>
|
|
168
|
+
<a href="/admin/seo/editor">Editor</a>
|
|
169
|
+
<a href="/admin/seo/reports">Reports</a>
|
|
170
|
+
<a href="/admin/seo/search">Search</a>
|
|
171
|
+
<a href="/admin/seo/settings">Settings</a>
|
|
172
|
+
</nav>
|
|
173
|
+
{/* Your SEO dashboard content */}
|
|
61
174
|
</div>
|
|
62
175
|
);
|
|
63
176
|
}
|
|
64
177
|
```
|
|
65
178
|
|
|
179
|
+
**`app/admin/seo/editor/page.tsx` (Editor):**
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
"use client";
|
|
183
|
+
|
|
184
|
+
import { useState, useEffect } from "react";
|
|
185
|
+
import { useSearchParams } from "next/navigation";
|
|
186
|
+
import type { SEORecord } from "@seo-console/package";
|
|
187
|
+
|
|
188
|
+
export default function EditorPage() {
|
|
189
|
+
const searchParams = useSearchParams();
|
|
190
|
+
const route = searchParams.get("route");
|
|
191
|
+
const [record, setRecord] = useState<SEORecord | null>(null);
|
|
192
|
+
const [formData, setFormData] = useState({
|
|
193
|
+
title: "",
|
|
194
|
+
description: "",
|
|
195
|
+
canonicalUrl: "",
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Load and save logic here
|
|
199
|
+
return (
|
|
200
|
+
<div>
|
|
201
|
+
<h1>Edit SEO Record</h1>
|
|
202
|
+
{/* Your editor form */}
|
|
203
|
+
</div>
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
> **Note:** For complete implementation examples, see the demo app in the repository. The package provides the data layer and utilities; you'll need to build the UI components or copy from the demo.
|
|
209
|
+
|
|
210
|
+
### Step 4: Add SEO Metadata to Your Pages
|
|
211
|
+
|
|
212
|
+
Use the `useGenerateMetadata` hook to automatically generate metadata from your SEO records:
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
// app/blog/[slug]/page.tsx
|
|
216
|
+
import { useGenerateMetadata } from "@seo-console/package/hooks";
|
|
217
|
+
|
|
218
|
+
export async function generateMetadata({ params }: { params: { slug: string } }) {
|
|
219
|
+
const metadata = await useGenerateMetadata({
|
|
220
|
+
routePath: `/blog/${params.slug}`,
|
|
221
|
+
fallback: {
|
|
222
|
+
title: "Blog Post",
|
|
223
|
+
description: "Default description"
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
return metadata;
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Step 5: Add to Your Admin Navigation
|
|
231
|
+
|
|
232
|
+
Add a link to the SEO admin section in your main admin navigation:
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
// app/admin/layout.tsx or your admin navigation component
|
|
236
|
+
<nav>
|
|
237
|
+
<Link href="/admin/dashboard">Dashboard</Link>
|
|
238
|
+
<Link href="/admin/seo">SEO</Link> {/* Add this */}
|
|
239
|
+
<Link href="/admin/users">Users</Link>
|
|
240
|
+
{/* ... other admin links */}
|
|
241
|
+
</nav>
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Quick Start Summary
|
|
245
|
+
|
|
246
|
+
1. **Install:** `npm install @seo-console/package`
|
|
247
|
+
2. **Create API route:** `app/api/seo-records/route.ts` (see Step 2)
|
|
248
|
+
3. **Create admin pages:** `app/admin/seo/` directory with pages (see Step 3)
|
|
249
|
+
4. **Add to navigation:** Link to `/admin/seo` in your admin menu
|
|
250
|
+
5. **Use in pages:** Add `generateMetadata` to your pages (see Step 4)
|
|
251
|
+
|
|
252
|
+
That's it! The SEO admin interface will be accessible at `/admin/seo` as a new tab in your admin area.
|
|
253
|
+
|
|
66
254
|
## API Reference
|
|
67
255
|
|
|
68
256
|
### Hooks
|
|
69
257
|
|
|
70
258
|
#### `useGenerateMetadata(options)`
|
|
71
259
|
|
|
72
|
-
Generates Next.js metadata from SEO records
|
|
260
|
+
Generates Next.js metadata from SEO records.
|
|
73
261
|
|
|
74
262
|
```typescript
|
|
75
263
|
import { useGenerateMetadata } from "@seo-console/package/hooks";
|
|
@@ -83,31 +271,37 @@ const metadata = await useGenerateMetadata({
|
|
|
83
271
|
});
|
|
84
272
|
```
|
|
85
273
|
|
|
86
|
-
###
|
|
87
|
-
|
|
88
|
-
#### `SEORecordList`
|
|
89
|
-
|
|
90
|
-
Displays a list of all SEO records with edit/delete functionality.
|
|
91
|
-
|
|
92
|
-
#### `SEORecordForm`
|
|
274
|
+
### Server-Side Functions
|
|
93
275
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
276
|
+
```typescript
|
|
277
|
+
import {
|
|
278
|
+
getSEORecords,
|
|
279
|
+
getSEORecordByRoute,
|
|
280
|
+
createSEORecord,
|
|
281
|
+
updateSEORecord,
|
|
282
|
+
deleteSEORecord,
|
|
283
|
+
generateSitemapFromRecords,
|
|
284
|
+
generateRobotsTxt,
|
|
285
|
+
discoverNextJSRoutes,
|
|
286
|
+
extractMetadataFromURL
|
|
287
|
+
} from "@seo-console/package/server";
|
|
288
|
+
```
|
|
99
289
|
|
|
100
|
-
|
|
290
|
+
## Storage Backends
|
|
101
291
|
|
|
102
|
-
|
|
292
|
+
### File Storage (Default)
|
|
103
293
|
|
|
104
|
-
|
|
294
|
+
- **No database required** - stores data in a JSON file
|
|
295
|
+
- **Perfect for small to medium sites** - simple and fast
|
|
296
|
+
- **File location**: `seo-records.json` (configurable via `SEO_CONSOLE_STORAGE_PATH`)
|
|
297
|
+
- **Automatic**: Works out of the box with no configuration
|
|
105
298
|
|
|
106
|
-
|
|
107
|
-
- `profiles` - User profiles (from migration 001)
|
|
108
|
-
- `seo_records` - SEO metadata records (from migration 002)
|
|
299
|
+
### Supabase Storage (Optional)
|
|
109
300
|
|
|
110
|
-
|
|
301
|
+
- **Database-backed** - uses Supabase PostgreSQL
|
|
302
|
+
- **Better for larger sites** - scalable and supports concurrent access
|
|
303
|
+
- **Requires**: Supabase project and migrations
|
|
304
|
+
- **Auto-detected**: If `NEXT_PUBLIC_SUPABASE_URL` and `NEXT_PUBLIC_SUPABASE_ANON_KEY` are set
|
|
111
305
|
|
|
112
306
|
## License
|
|
113
307
|
|