@ontosdk/next 1.2.0 → 1.3.0
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/JSON_LD_GUIDE.md +403 -0
- package/LLMS_TXT_GUIDE.md +297 -0
- package/ONTOROVIDER_USAGE.md +130 -0
- package/QUICKSTART.md +71 -0
- package/README.md +253 -0
- package/SCHEMA_QUICKSTART.md +97 -0
- package/dist/OntoHead.d.mts +27 -0
- package/dist/OntoHead.d.ts +27 -0
- package/dist/OntoHead.js +2 -0
- package/dist/OntoHead.js.map +1 -0
- package/dist/OntoHead.mjs +2 -0
- package/dist/OntoHead.mjs.map +1 -0
- package/dist/OntoProvider.d.mts +52 -0
- package/dist/OntoProvider.d.ts +52 -0
- package/dist/OntoProvider.js +2 -0
- package/dist/OntoProvider.js.map +1 -0
- package/dist/OntoProvider.mjs +2 -0
- package/dist/OntoProvider.mjs.map +1 -0
- package/dist/config.d.mts +85 -0
- package/dist/config.d.ts +85 -0
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -0
- package/dist/config.mjs +4 -0
- package/dist/config.mjs.map +1 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -4
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.d.mts +1 -1
- package/dist/middleware.d.ts +1 -1
- package/dist/middleware.js +4 -2
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +4 -2
- package/dist/middleware.mjs.map +1 -1
- package/dist/schemas.d.mts +73 -0
- package/dist/schemas.d.ts +73 -0
- package/dist/schemas.js +2 -0
- package/dist/schemas.js.map +1 -0
- package/dist/schemas.mjs +2 -0
- package/dist/schemas.mjs.map +1 -0
- package/onto.config.example.ts +111 -0
- package/package.json +28 -2
- package/src/OntoHead.tsx +59 -0
- package/src/OntoProvider.tsx +95 -0
- package/src/bots.ts +6 -3
- package/src/config.ts +151 -0
- package/src/index.ts +14 -0
- package/src/middleware.ts +56 -8
- package/src/schemas.ts +186 -0
- package/tsconfig.json +1 -0
- package/tsup.config.ts +2 -2
package/JSON_LD_GUIDE.md
ADDED
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
# Automatic JSON-LD Schema Injection Guide
|
|
2
|
+
|
|
3
|
+
The OntoProvider now automatically injects JSON-LD structured data schemas based on your page configuration. **Zero manual JSON-LD writing required** - just configure your routes and the SDK does the rest.
|
|
4
|
+
|
|
5
|
+
## Why JSON-LD Matters for AI
|
|
6
|
+
|
|
7
|
+
JSON-LD (JavaScript Object Notation for Linked Data) is a lightweight format that helps AI agents:
|
|
8
|
+
- **Understand your content** with high confidence
|
|
9
|
+
- **Extract structured data** (pricing, products, methodology)
|
|
10
|
+
- **Reduce hallucinations** by providing authoritative schema markup
|
|
11
|
+
- **Score higher** on AIO metrics (worth 25 points in our scoring algorithm)
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### 1. Import Your Config
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
// app/layout.tsx
|
|
19
|
+
import { OntoProvider } from '@ontosdk/next/provider';
|
|
20
|
+
import config from '../onto.config';
|
|
21
|
+
|
|
22
|
+
export default function RootLayout({ children }) {
|
|
23
|
+
return (
|
|
24
|
+
<OntoProvider baseUrl="https://example.com" config={config}>
|
|
25
|
+
<html>
|
|
26
|
+
<head />
|
|
27
|
+
<body>{children}</body>
|
|
28
|
+
</html>
|
|
29
|
+
</OntoProvider>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 2. Configure Page Types
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
// onto.config.ts
|
|
38
|
+
import type { OntoConfig } from '@ontosdk/next';
|
|
39
|
+
|
|
40
|
+
const config: OntoConfig = {
|
|
41
|
+
name: 'My Site',
|
|
42
|
+
summary: 'Description',
|
|
43
|
+
baseUrl: 'https://example.com',
|
|
44
|
+
|
|
45
|
+
routes: [
|
|
46
|
+
{
|
|
47
|
+
path: '/score',
|
|
48
|
+
description: 'AIO Score Calculator',
|
|
49
|
+
pageType: 'scoring' // ← Automatically injects Methodology schema
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
path: '/about',
|
|
53
|
+
description: 'About us',
|
|
54
|
+
pageType: 'about' // ← Automatically injects Organization schema
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
|
|
58
|
+
organization: {
|
|
59
|
+
name: 'My Company',
|
|
60
|
+
description: 'What we do',
|
|
61
|
+
url: 'https://example.com',
|
|
62
|
+
logo: 'https://example.com/logo.png'
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export default config;
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 3. That's It!
|
|
70
|
+
|
|
71
|
+
The OntoProvider automatically:
|
|
72
|
+
1. Detects the current page path
|
|
73
|
+
2. Matches it against your route configuration
|
|
74
|
+
3. Generates the appropriate JSON-LD schema
|
|
75
|
+
4. Injects it into the page `<head>`
|
|
76
|
+
|
|
77
|
+
No manual `<script type="application/ld+json">` tags needed!
|
|
78
|
+
|
|
79
|
+
## Supported Page Types
|
|
80
|
+
|
|
81
|
+
### `pageType: 'scoring'`
|
|
82
|
+
|
|
83
|
+
**Use for**: AIO score calculators, methodology pages, scoring tools
|
|
84
|
+
|
|
85
|
+
**Generates**: [HowTo Schema](https://schema.org/HowTo) explaining the AIO scoring methodology
|
|
86
|
+
|
|
87
|
+
**Includes**:
|
|
88
|
+
- 4-step methodology (Content Negotiation, Token Efficiency, Structured Data, Semantic HTML)
|
|
89
|
+
- Standard AIO weights (40%, 35%, 25%, bonus)
|
|
90
|
+
- Detailed explanations for each metric
|
|
91
|
+
|
|
92
|
+
**Example output**:
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"@context": "https://schema.org",
|
|
96
|
+
"@type": "HowTo",
|
|
97
|
+
"name": "AIO Score Calculation Methodology",
|
|
98
|
+
"description": "AI Optimization (AIO) Score measures how well a website is optimized for AI agents...",
|
|
99
|
+
"step": [
|
|
100
|
+
{
|
|
101
|
+
"@type": "HowToStep",
|
|
102
|
+
"name": "Content Negotiation",
|
|
103
|
+
"text": "Check if the site responds to Accept: text/markdown header. Weight: 40%...",
|
|
104
|
+
"position": 1
|
|
105
|
+
},
|
|
106
|
+
// ... 3 more steps
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**When to use**:
|
|
112
|
+
- `/score` - Score calculator pages
|
|
113
|
+
- `/methodology` - Explanation of scoring system
|
|
114
|
+
- `/calculator` - Any page with a scoring/grading tool
|
|
115
|
+
|
|
116
|
+
### `pageType: 'about'`
|
|
117
|
+
|
|
118
|
+
**Use for**: About pages, company info, team pages
|
|
119
|
+
|
|
120
|
+
**Generates**: [AboutPage Schema](https://schema.org/AboutPage) + [Organization Schema](https://schema.org/Organization)
|
|
121
|
+
|
|
122
|
+
**Includes**:
|
|
123
|
+
- Organization name, description, URL
|
|
124
|
+
- Logo, founding date (if provided)
|
|
125
|
+
- Nested organization entity
|
|
126
|
+
|
|
127
|
+
**Example output**:
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"@context": "https://schema.org",
|
|
131
|
+
"@type": "AboutPage",
|
|
132
|
+
"name": "About My Company",
|
|
133
|
+
"url": "https://example.com/about",
|
|
134
|
+
"description": "Company description from config",
|
|
135
|
+
"mainEntity": {
|
|
136
|
+
"@context": "https://schema.org",
|
|
137
|
+
"@type": "Organization",
|
|
138
|
+
"name": "My Company",
|
|
139
|
+
"url": "https://example.com",
|
|
140
|
+
"description": "What we do",
|
|
141
|
+
"logo": "https://example.com/logo.png",
|
|
142
|
+
"foundingDate": "2024-01-01"
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**When to use**:
|
|
148
|
+
- `/about` - Company about page
|
|
149
|
+
- `/about-us` - Team/company info
|
|
150
|
+
- `/company` - Organization details
|
|
151
|
+
|
|
152
|
+
### `pageType: 'default'` (or omitted)
|
|
153
|
+
|
|
154
|
+
**Use for**: All other pages
|
|
155
|
+
|
|
156
|
+
**Generates**: Nothing - no automatic JSON-LD injection
|
|
157
|
+
|
|
158
|
+
Use this for pages where you want to manually control JSON-LD or don't need structured data.
|
|
159
|
+
|
|
160
|
+
## Configuration Reference
|
|
161
|
+
|
|
162
|
+
### Route Configuration
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
interface OntoRoute {
|
|
166
|
+
path: string; // URL path (e.g., '/score')
|
|
167
|
+
description: string; // What this page contains
|
|
168
|
+
pageType?: PageType; // 'scoring' | 'about' | 'default'
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Organization Configuration
|
|
173
|
+
|
|
174
|
+
Required for `pageType: 'about'` to work properly:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
organization?: {
|
|
178
|
+
name: string; // Required: Organization name
|
|
179
|
+
description?: string; // Optional: What you do
|
|
180
|
+
url?: string; // Optional: Company website
|
|
181
|
+
logo?: string; // Optional: Logo URL (use absolute URL)
|
|
182
|
+
foundingDate?: string; // Optional: ISO date format (YYYY-MM-DD)
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Complete Example
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
// onto.config.ts
|
|
190
|
+
import type { OntoConfig } from '@ontosdk/next';
|
|
191
|
+
|
|
192
|
+
const config: OntoConfig = {
|
|
193
|
+
name: 'BuildOnto',
|
|
194
|
+
summary: 'Next.js infrastructure for AI-optimized websites',
|
|
195
|
+
baseUrl: 'https://buildonto.dev',
|
|
196
|
+
|
|
197
|
+
routes: [
|
|
198
|
+
{
|
|
199
|
+
path: '/',
|
|
200
|
+
description: 'Homepage',
|
|
201
|
+
pageType: 'default'
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
path: '/score',
|
|
205
|
+
description: 'AIO Score Calculator - grade your AI optimization',
|
|
206
|
+
pageType: 'scoring'
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
path: '/about',
|
|
210
|
+
description: 'About BuildOnto and our mission',
|
|
211
|
+
pageType: 'about'
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
path: '/docs',
|
|
215
|
+
description: 'Documentation and guides'
|
|
216
|
+
// No pageType = 'default', no automatic JSON-LD
|
|
217
|
+
}
|
|
218
|
+
],
|
|
219
|
+
|
|
220
|
+
organization: {
|
|
221
|
+
name: 'BuildOnto',
|
|
222
|
+
description: 'Making websites AI-ready with zero-config infrastructure',
|
|
223
|
+
url: 'https://buildonto.dev',
|
|
224
|
+
logo: 'https://buildonto.dev/logo.png',
|
|
225
|
+
foundingDate: '2024-01-01'
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export default config;
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
// app/layout.tsx
|
|
234
|
+
import { OntoProvider } from '@ontosdk/next/provider';
|
|
235
|
+
import config from '../onto.config';
|
|
236
|
+
|
|
237
|
+
export default function RootLayout({ children }) {
|
|
238
|
+
return (
|
|
239
|
+
<OntoProvider baseUrl="https://buildonto.dev" config={config}>
|
|
240
|
+
<html lang="en">
|
|
241
|
+
<head />
|
|
242
|
+
<body>{children}</body>
|
|
243
|
+
</html>
|
|
244
|
+
</OntoProvider>
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Now visit `/score` or `/about` and view source - you'll see the JSON-LD automatically injected!
|
|
250
|
+
|
|
251
|
+
## AIO Scoring Weights
|
|
252
|
+
|
|
253
|
+
The `pageType: 'scoring'` schema includes the official AIO scoring methodology:
|
|
254
|
+
|
|
255
|
+
| Metric | Weight | Max Penalty | Description |
|
|
256
|
+
|--------|--------|-------------|-------------|
|
|
257
|
+
| **Content Negotiation** | 40% | -30 points | Accept: text/markdown support |
|
|
258
|
+
| **Token Efficiency** | 35% | -30 points | HTML size vs visible text ratio |
|
|
259
|
+
| **Structured Data** | 25% | -25 points | JSON-LD presence (this feature!) |
|
|
260
|
+
| **Semantic HTML** | Bonus | -15 points | `<main>`, `<article>` tags |
|
|
261
|
+
|
|
262
|
+
By using this SDK with automatic JSON-LD injection, you instantly gain **+25 points** on the AIO score!
|
|
263
|
+
|
|
264
|
+
## Validation
|
|
265
|
+
|
|
266
|
+
### Test Your Schema
|
|
267
|
+
|
|
268
|
+
1. Visit your page in development: `http://localhost:3000/score`
|
|
269
|
+
2. View page source (Ctrl+U / Cmd+U)
|
|
270
|
+
3. Look for `<script type="application/ld+json">`
|
|
271
|
+
4. Copy the JSON content
|
|
272
|
+
5. Validate at [Google's Rich Results Test](https://search.google.com/test/rich-results)
|
|
273
|
+
|
|
274
|
+
### Check with cURL
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
# Fetch as an AI bot
|
|
278
|
+
curl -H "User-Agent: GPTBot" http://localhost:3000/score | grep "application/ld+json"
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Advanced Usage
|
|
282
|
+
|
|
283
|
+
### Manual Schema Generation
|
|
284
|
+
|
|
285
|
+
If you need custom schemas beyond the built-in types:
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
import { generateAIOMethodologySchema } from '@ontosdk/next';
|
|
289
|
+
|
|
290
|
+
const schema = generateAIOMethodologySchema(config, 'https://example.com/score');
|
|
291
|
+
console.log(JSON.stringify(schema, null, 2));
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Custom Page Types
|
|
295
|
+
|
|
296
|
+
Want to add your own page types? Extend the config:
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
// Create a custom schema generator
|
|
300
|
+
function generateProductSchema(config, url) {
|
|
301
|
+
return {
|
|
302
|
+
'@context': 'https://schema.org',
|
|
303
|
+
'@type': 'Product',
|
|
304
|
+
name: config.name,
|
|
305
|
+
url: url
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Use it manually in your component
|
|
310
|
+
import { serializeSchema } from '@ontosdk/next';
|
|
311
|
+
|
|
312
|
+
const jsonLd = serializeSchema(generateProductSchema(config, pageUrl));
|
|
313
|
+
|
|
314
|
+
return (
|
|
315
|
+
<script
|
|
316
|
+
type="application/ld+json"
|
|
317
|
+
dangerouslySetInnerHTML={{ __html: jsonLd }}
|
|
318
|
+
/>
|
|
319
|
+
);
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Migration from Manual JSON-LD
|
|
323
|
+
|
|
324
|
+
If you currently have manual JSON-LD:
|
|
325
|
+
|
|
326
|
+
**Before** (manual):
|
|
327
|
+
```tsx
|
|
328
|
+
export default function AboutPage() {
|
|
329
|
+
return (
|
|
330
|
+
<>
|
|
331
|
+
<script
|
|
332
|
+
type="application/ld+json"
|
|
333
|
+
dangerouslySetInnerHTML={{
|
|
334
|
+
__html: JSON.stringify({
|
|
335
|
+
'@context': 'https://schema.org',
|
|
336
|
+
'@type': 'AboutPage',
|
|
337
|
+
name: 'About Us',
|
|
338
|
+
// ... lots of manual JSON
|
|
339
|
+
})
|
|
340
|
+
}}
|
|
341
|
+
/>
|
|
342
|
+
<main>{/* content */}</main>
|
|
343
|
+
</>
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**After** (automatic):
|
|
349
|
+
```tsx
|
|
350
|
+
// onto.config.ts
|
|
351
|
+
routes: [
|
|
352
|
+
{ path: '/about', description: 'About us', pageType: 'about' }
|
|
353
|
+
]
|
|
354
|
+
|
|
355
|
+
// app/layout.tsx - just wrap once
|
|
356
|
+
<OntoProvider config={config} baseUrl="https://example.com">
|
|
357
|
+
{children}
|
|
358
|
+
</OntoProvider>
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## Benefits
|
|
362
|
+
|
|
363
|
+
✅ **Zero Manual Work**: Configure once, works everywhere
|
|
364
|
+
✅ **Type-Safe**: Full TypeScript support with intellisense
|
|
365
|
+
✅ **Consistent**: Same schema structure across all pages
|
|
366
|
+
✅ **Maintainable**: Update in one place (config) instead of per-page
|
|
367
|
+
✅ **AIO Optimized**: Schemas designed specifically for AI agents
|
|
368
|
+
✅ **Schema.org Compliant**: Follows official standards
|
|
369
|
+
✅ **Validation Ready**: Works with Google Rich Results Test
|
|
370
|
+
|
|
371
|
+
## Troubleshooting
|
|
372
|
+
|
|
373
|
+
### Schema not appearing?
|
|
374
|
+
|
|
375
|
+
1. **Check config path**: Make sure you're importing the config correctly
|
|
376
|
+
2. **Verify route match**: Path must exactly match (including trailing slashes)
|
|
377
|
+
3. **Check pageType**: Must be explicitly set to 'scoring' or 'about'
|
|
378
|
+
4. **Organization missing**: For 'about' pages, ensure `organization` is configured
|
|
379
|
+
|
|
380
|
+
### Wrong schema type?
|
|
381
|
+
|
|
382
|
+
- Double-check the `pageType` value in your route config
|
|
383
|
+
- Ensure you're passing the config prop to OntoProvider
|
|
384
|
+
|
|
385
|
+
### TypeScript errors?
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
npm install @ontosdk/next@latest
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
Make sure you're on the latest version with schema support.
|
|
392
|
+
|
|
393
|
+
## Resources
|
|
394
|
+
|
|
395
|
+
- [Schema.org: HowTo](https://schema.org/HowTo)
|
|
396
|
+
- [Schema.org: AboutPage](https://schema.org/AboutPage)
|
|
397
|
+
- [Schema.org: Organization](https://schema.org/Organization)
|
|
398
|
+
- [Google Rich Results Test](https://search.google.com/test/rich-results)
|
|
399
|
+
- [AIO Score Documentation](https://buildonto.dev/docs/aio-score)
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
**Next Steps**: Check out [LLMS_TXT_GUIDE.md](./LLMS_TXT_GUIDE.md) for automatic llms.txt generation!
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# Dynamic llms.txt Generation Guide
|
|
2
|
+
|
|
3
|
+
The Onto middleware now supports **dynamic llms.txt generation** from your `onto.config.ts` file. This means you never have to manually create or update an `llms.txt` file—it's generated on-the-fly from your configuration.
|
|
4
|
+
|
|
5
|
+
## What is llms.txt?
|
|
6
|
+
|
|
7
|
+
`llms.txt` is a standardized file format that provides AI agents (like ChatGPT, Claude, and Perplexity) with a concise, structured overview of your website. It follows a simple Markdown format and helps AI systems understand:
|
|
8
|
+
|
|
9
|
+
- What your site is about
|
|
10
|
+
- Where the most important content is located
|
|
11
|
+
- What resources are available
|
|
12
|
+
|
|
13
|
+
**Key Benefits:**
|
|
14
|
+
- AI agents get accurate, up-to-date information about your site
|
|
15
|
+
- No manual file maintenance—generated from config
|
|
16
|
+
- Follows the official llms.txt specification
|
|
17
|
+
- Automatically served to AI crawlers by the middleware
|
|
18
|
+
|
|
19
|
+
## Setup
|
|
20
|
+
|
|
21
|
+
### 1. Create `onto.config.ts`
|
|
22
|
+
|
|
23
|
+
Create a file named `onto.config.ts` in your project root:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { OntoConfig } from '@ontosdk/next';
|
|
27
|
+
|
|
28
|
+
const config: OntoConfig = {
|
|
29
|
+
name: 'My Project',
|
|
30
|
+
summary: 'A brief description of what your project does and who it serves.',
|
|
31
|
+
baseUrl: 'https://example.com',
|
|
32
|
+
|
|
33
|
+
routes: [
|
|
34
|
+
{ path: '/', description: 'Homepage' },
|
|
35
|
+
{ path: '/docs', description: 'Documentation' },
|
|
36
|
+
{ path: '/api', description: 'API reference' }
|
|
37
|
+
]
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default config;
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 2. Middleware Configuration
|
|
44
|
+
|
|
45
|
+
If you've already installed the Onto middleware, you're done! The middleware automatically:
|
|
46
|
+
1. Detects requests to `/llms.txt`
|
|
47
|
+
2. Loads your `onto.config.ts`
|
|
48
|
+
3. Generates the llms.txt content dynamically
|
|
49
|
+
4. Returns it with proper headers (`Content-Type: text/plain`)
|
|
50
|
+
|
|
51
|
+
No additional configuration needed.
|
|
52
|
+
|
|
53
|
+
## Configuration Schema
|
|
54
|
+
|
|
55
|
+
### Required Fields
|
|
56
|
+
|
|
57
|
+
#### `name` (string)
|
|
58
|
+
The name of your project or website. Used as the H1 heading in llms.txt.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
name: 'Acme Corp Documentation'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### `summary` (string)
|
|
65
|
+
A concise summary of your project. Should contain key information that helps AI agents understand the purpose and scope of your site. Displayed as a blockquote in llms.txt.
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
summary: 'Comprehensive documentation for the Acme API. Includes REST endpoints, SDKs, and integration guides for Python, JavaScript, and Go.'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### `baseUrl` (string)
|
|
72
|
+
The base URL of your website. Used to construct full URLs for routes.
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
baseUrl: 'https://docs.acme.com'
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Optional Fields
|
|
79
|
+
|
|
80
|
+
#### `routes` (array)
|
|
81
|
+
Key routes that AI agents should know about. Each route includes:
|
|
82
|
+
- `path`: The URL path (e.g., `/docs/api`)
|
|
83
|
+
- `description`: What this route contains
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
routes: [
|
|
87
|
+
{
|
|
88
|
+
path: '/docs/getting-started',
|
|
89
|
+
description: 'Quick start guide for new developers'
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
path: '/docs/api/reference',
|
|
93
|
+
description: 'Complete API endpoint reference'
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
path: '/blog',
|
|
97
|
+
description: 'Technical blog and release notes'
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### `externalLinks` (array)
|
|
103
|
+
Links to external resources like GitHub, status pages, or community forums.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
externalLinks: [
|
|
107
|
+
{
|
|
108
|
+
title: 'GitHub Repository',
|
|
109
|
+
url: 'https://github.com/acme/sdk',
|
|
110
|
+
description: 'Source code and issue tracker'
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
title: 'API Status',
|
|
114
|
+
url: 'https://status.acme.com'
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### `sections` (array)
|
|
120
|
+
Custom markdown sections to add additional context. Each section has:
|
|
121
|
+
- `heading`: The section title
|
|
122
|
+
- `content`: Markdown content
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
sections: [
|
|
126
|
+
{
|
|
127
|
+
heading: 'About',
|
|
128
|
+
content: 'Acme provides cloud infrastructure for modern applications...'
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
heading: 'Key Features',
|
|
132
|
+
content: `- **Fast**: Sub-millisecond response times
|
|
133
|
+
- **Secure**: SOC 2 Type II certified
|
|
134
|
+
- **Scalable**: Handles millions of requests per second`
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Example Output
|
|
140
|
+
|
|
141
|
+
With the following config:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
const config: OntoConfig = {
|
|
145
|
+
name: 'Acme Documentation',
|
|
146
|
+
summary: 'API docs and guides for Acme Cloud Platform',
|
|
147
|
+
baseUrl: 'https://docs.acme.com',
|
|
148
|
+
routes: [
|
|
149
|
+
{ path: '/api', description: 'API reference' },
|
|
150
|
+
{ path: '/guides', description: 'Integration guides' }
|
|
151
|
+
]
|
|
152
|
+
};
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The generated `/llms.txt` will be:
|
|
156
|
+
|
|
157
|
+
```markdown
|
|
158
|
+
# Acme Documentation
|
|
159
|
+
|
|
160
|
+
> API docs and guides for Acme Cloud Platform
|
|
161
|
+
|
|
162
|
+
## Key Routes
|
|
163
|
+
|
|
164
|
+
- [/api](https://docs.acme.com/api): API reference
|
|
165
|
+
- [/guides](https://docs.acme.com/guides): Integration guides
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Advanced Usage
|
|
169
|
+
|
|
170
|
+
### TypeScript Support
|
|
171
|
+
|
|
172
|
+
Full TypeScript support with type checking:
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import type { OntoConfig } from '@ontosdk/next';
|
|
176
|
+
|
|
177
|
+
const config: OntoConfig = {
|
|
178
|
+
name: 'My Site',
|
|
179
|
+
summary: 'Description',
|
|
180
|
+
baseUrl: 'https://example.com',
|
|
181
|
+
// TypeScript will validate all fields
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
export default config;
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Environment-Specific Configuration
|
|
188
|
+
|
|
189
|
+
Use environment variables for different deployment environments:
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
const config: OntoConfig = {
|
|
193
|
+
name: 'My App',
|
|
194
|
+
summary: 'A great application',
|
|
195
|
+
baseUrl: process.env.NEXT_PUBLIC_BASE_URL || 'https://example.com',
|
|
196
|
+
|
|
197
|
+
routes: [
|
|
198
|
+
{ path: '/', description: 'Home' },
|
|
199
|
+
...(process.env.NODE_ENV === 'production'
|
|
200
|
+
? [{ path: '/enterprise', description: 'Enterprise features' }]
|
|
201
|
+
: []
|
|
202
|
+
)
|
|
203
|
+
]
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export default config;
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Dynamic Routes
|
|
210
|
+
|
|
211
|
+
Generate routes programmatically:
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
const docPages = ['getting-started', 'authentication', 'webhooks'];
|
|
215
|
+
|
|
216
|
+
const config: OntoConfig = {
|
|
217
|
+
name: 'API Docs',
|
|
218
|
+
summary: 'Developer documentation',
|
|
219
|
+
baseUrl: 'https://api.example.com',
|
|
220
|
+
|
|
221
|
+
routes: [
|
|
222
|
+
{ path: '/', description: 'API overview' },
|
|
223
|
+
...docPages.map(page => ({
|
|
224
|
+
path: `/docs/${page}`,
|
|
225
|
+
description: `Guide: ${page.replace('-', ' ')}`
|
|
226
|
+
}))
|
|
227
|
+
]
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
export default config;
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Fallback Behavior
|
|
234
|
+
|
|
235
|
+
The middleware implements intelligent fallback:
|
|
236
|
+
|
|
237
|
+
1. **With config**: Generates llms.txt dynamically from `onto.config.ts`
|
|
238
|
+
2. **Without config**: Falls back to static `public/llms.txt` if it exists
|
|
239
|
+
3. **On error**: Logs error and attempts to serve static file
|
|
240
|
+
|
|
241
|
+
This ensures your site always has an llms.txt, even if configuration fails.
|
|
242
|
+
|
|
243
|
+
## Caching
|
|
244
|
+
|
|
245
|
+
Generated llms.txt responses include optimal cache headers:
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
Content-Type: text/plain; charset=utf-8
|
|
249
|
+
Cache-Control: public, max-age=3600, s-maxage=3600, stale-while-revalidate=86400
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
This means:
|
|
253
|
+
- Cached for 1 hour in browsers/CDNs
|
|
254
|
+
- Stale content can be served for up to 24 hours while revalidating
|
|
255
|
+
- Reduces server load and improves response times
|
|
256
|
+
|
|
257
|
+
## Debugging
|
|
258
|
+
|
|
259
|
+
To verify your llms.txt is being generated correctly:
|
|
260
|
+
|
|
261
|
+
1. **Start your dev server**: `npm run dev`
|
|
262
|
+
2. **Visit**: `http://localhost:3000/llms.txt`
|
|
263
|
+
3. **Check console**: Look for `[Onto] Failed to generate llms.txt:` errors
|
|
264
|
+
|
|
265
|
+
If you see your generated content, you're all set!
|
|
266
|
+
|
|
267
|
+
## Migration from Static llms.txt
|
|
268
|
+
|
|
269
|
+
If you currently have a static `public/llms.txt` file:
|
|
270
|
+
|
|
271
|
+
1. Create `onto.config.ts` with your site information
|
|
272
|
+
2. Test that `/llms.txt` is being generated correctly
|
|
273
|
+
3. Delete `public/llms.txt` (optional—it's used as fallback)
|
|
274
|
+
|
|
275
|
+
The middleware will automatically prefer the dynamic version.
|
|
276
|
+
|
|
277
|
+
## Specification Compliance
|
|
278
|
+
|
|
279
|
+
This implementation follows the official llms.txt specification:
|
|
280
|
+
|
|
281
|
+
- ✅ H1 with project name (required)
|
|
282
|
+
- ✅ Blockquote with summary (required)
|
|
283
|
+
- ✅ Additional markdown sections (optional)
|
|
284
|
+
- ✅ Proper content type (`text/plain`)
|
|
285
|
+
- ✅ UTF-8 encoding
|
|
286
|
+
|
|
287
|
+
## Resources
|
|
288
|
+
|
|
289
|
+
- [llms.txt Official Site](https://llmstxt.org/)
|
|
290
|
+
- [llms.txt Specification](https://llmstxt.org/spec)
|
|
291
|
+
- [Example Sites](https://llmstxt.org/examples)
|
|
292
|
+
|
|
293
|
+
## Support
|
|
294
|
+
|
|
295
|
+
For questions or issues:
|
|
296
|
+
- GitHub: [onto-sdk/issues](https://github.com/anthropics/onto-sdk/issues)
|
|
297
|
+
- Docs: [buildonto.dev/docs](https://buildonto.dev/docs)
|