Skip to content

Commit 460f081

Browse files
feat: Optimized site for AI SEO
1 parent c685475 commit 460f081

15 files changed

Lines changed: 543 additions & 51 deletions

File tree

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { NextRequest, NextResponse } from 'next/server'
2+
import { getPublishedSkill } from '@/lib/agent-skills'
3+
4+
type RouteParams = {
5+
params: Promise<{
6+
skill: string
7+
}>
8+
}
9+
10+
export async function GET(_request: NextRequest, { params }: RouteParams) {
11+
const { skill } = await params
12+
const publishedSkill = getPublishedSkill(skill)
13+
14+
if (!publishedSkill) {
15+
return NextResponse.json({ error: 'Skill not found' }, { status: 404 })
16+
}
17+
18+
return new NextResponse(publishedSkill.content, {
19+
headers: {
20+
'Content-Type': 'text/markdown; charset=utf-8',
21+
},
22+
})
23+
}
24+
25+
export async function HEAD(_request: NextRequest, { params }: RouteParams) {
26+
const { skill } = await params
27+
const publishedSkill = getPublishedSkill(skill)
28+
29+
if (!publishedSkill) {
30+
return new NextResponse(null, { status: 404 })
31+
}
32+
33+
return new NextResponse(null, {
34+
headers: {
35+
'Content-Type': 'text/markdown; charset=utf-8',
36+
},
37+
})
38+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { NextResponse } from 'next/server'
2+
import { publishedSkills } from '@/lib/agent-skills'
3+
4+
const schemaUrl = 'https://schemas.agentskills.io/discovery/0.2.0/schema.json'
5+
6+
function buildIndexBody() {
7+
return {
8+
$schema: schemaUrl,
9+
skills: publishedSkills.map(({ name, type, description, url, digest }) => ({
10+
name,
11+
type,
12+
description,
13+
url,
14+
digest,
15+
})),
16+
}
17+
}
18+
19+
export function GET() {
20+
return NextResponse.json(buildIndexBody(), {
21+
headers: {
22+
'Content-Type': 'application/json; charset=utf-8',
23+
},
24+
})
25+
}
26+
27+
export function HEAD() {
28+
return new NextResponse(null, {
29+
headers: {
30+
'Content-Type': 'application/json; charset=utf-8',
31+
},
32+
})
33+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { NextRequest, NextResponse } from 'next/server'
2+
3+
export function GET(request: NextRequest) {
4+
const origin = request.nextUrl.origin
5+
const apiBase = `${origin}/api`
6+
7+
const body = {
8+
linkset: [
9+
{
10+
anchor: apiBase,
11+
'service-desc': [
12+
{
13+
href: `${origin}/openapi.json`,
14+
type: 'application/openapi+json',
15+
},
16+
],
17+
'service-doc': [
18+
{
19+
href: `${origin}/api-docs`,
20+
type: 'text/html',
21+
},
22+
],
23+
status: [
24+
{
25+
href: `${apiBase}/health`,
26+
type: 'application/json',
27+
},
28+
],
29+
},
30+
],
31+
}
32+
33+
return NextResponse.json(body, {
34+
headers: {
35+
'Content-Type': 'application/linkset+json; charset=utf-8',
36+
},
37+
})
38+
}

app/agent-markdown/route.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { NextRequest, NextResponse } from 'next/server'
2+
3+
function estimateTokenCount(markdown: string): number {
4+
return Math.max(1, Math.ceil(markdown.length / 4))
5+
}
6+
7+
export function GET(request: NextRequest) {
8+
const sourcePath = request.nextUrl.searchParams.get('source') || '/'
9+
10+
const markdown = `# Dev Weekends
11+
12+
Dev Weekends (DW) is Pakistan's number 1 software engineering community for students and early-career developers who want to grow fast with practical, real-world learning.
13+
14+
## What Dev Weekends is
15+
16+
- A community-first learning platform focused on software engineering and career growth.
17+
- A place where developers learn by building, shipping, and getting feedback from mentors.
18+
- A support system for people preparing for internships, jobs, freelancing, and global remote work.
19+
20+
## How we work
21+
22+
1. Weekly and weekend sessions led by industry professionals.
23+
2. Mentorship tracks with focused guidance and accountability.
24+
3. Community projects and open-source collaboration.
25+
4. Career support through interview prep, networking, and role-based guidance.
26+
27+
## Accessibility and cost
28+
29+
Everything at Dev Weekends is free for the community. Our core mission is to make high-quality tech mentorship and learning accessible for everyone.
30+
31+
## Primary links
32+
33+
- Website: https://devweekends.com
34+
- Sessions: https://devweekends.com/sessions
35+
- Community: https://devweekends.com/community
36+
- Mentorship: https://devweekends.com/mentorship
37+
- Projects: https://devweekends.com/projects
38+
39+
## Agent and machine-readable discovery
40+
41+
- Requested path: ${sourcePath}
42+
- llms.txt: https://devweekends.com/llms.txt
43+
- API catalog: https://devweekends.com/.well-known/api-catalog
44+
- Agent skills index: https://devweekends.com/.well-known/agent-skills/index.json
45+
`
46+
47+
return new NextResponse(markdown, {
48+
headers: {
49+
'Content-Type': 'text/markdown; charset=utf-8',
50+
'x-markdown-tokens': String(estimateTokenCount(markdown)),
51+
},
52+
})
53+
}

app/api-docs/page.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export default function ApiDocsPage() {
2+
return (
3+
<section className="mx-auto max-w-3xl px-4 py-16">
4+
<h1 className="text-3xl font-semibold tracking-tight">API Documentation</h1>
5+
<p className="mt-4 text-muted-foreground">
6+
This service publishes an API catalog for automated API discovery per RFC
7+
9727.
8+
</p>
9+
<p className="mt-2 text-muted-foreground">
10+
Machine-readable API description is available at <code>/openapi.json</code>,
11+
and health status is available at <code>/api/health</code>.
12+
</p>
13+
</section>
14+
)
15+
}

app/api/health/route.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { NextResponse } from 'next/server'
2+
3+
export function GET() {
4+
return NextResponse.json(
5+
{
6+
status: 'ok',
7+
service: 'devweekends-api',
8+
timestamp: new Date().toISOString(),
9+
},
10+
{
11+
status: 200,
12+
},
13+
)
14+
}

app/layout.tsx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ const geist = Geist({ subsets: ["latin"] })
1313

1414
export const metadata: Metadata = {
1515
metadataBase: new URL('https://devweekends.com'),
16+
alternates: {
17+
canonical: '/',
18+
},
1619
title: {
1720
default: "Dev Weekends - Your Gateway to becoming a better Software Engineer",
1821
template: "%s | Dev Weekends"
@@ -78,6 +81,38 @@ export const metadata: Metadata = {
7881
},
7982
}
8083

84+
const structuredData = {
85+
'@context': 'https://schema.org',
86+
'@graph': [
87+
{
88+
'@type': 'Organization',
89+
name: 'Dev Weekends',
90+
url: 'https://devweekends.com',
91+
logo: 'https://devweekends.com/favicons/android-chrome-512x512.png',
92+
sameAs: [
93+
'https://www.linkedin.com/company/devweekends/',
94+
'https://www.instagram.com/devweekends',
95+
],
96+
},
97+
{
98+
'@type': 'WebSite',
99+
name: 'Dev Weekends',
100+
url: 'https://devweekends.com',
101+
description:
102+
'Learning community for software engineers through events, mentorship, projects, and programs.',
103+
publisher: {
104+
'@type': 'Organization',
105+
name: 'Dev Weekends',
106+
},
107+
potentialAction: {
108+
'@type': 'SearchAction',
109+
target: 'https://devweekends.com/sessions',
110+
'query-input': 'required name=search_term_string',
111+
},
112+
},
113+
],
114+
}
115+
81116
export default function RootLayout({
82117
children,
83118
}: Readonly<{
@@ -91,6 +126,20 @@ export default function RootLayout({
91126
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png" />
92127
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png" />
93128
<link rel="manifest" href="/favicons/site.webmanifest" />
129+
<link rel="alternate" type="text/plain" href="/llms.txt" title="LLMs.txt" />
130+
<link rel="alternate" type="text/plain" href="/llms-full.txt" title="LLMs Full" />
131+
<link
132+
rel="alternate"
133+
type="application/json"
134+
href="/.well-known/agent-skills/index.json"
135+
title="Agent Skills Index"
136+
/>
137+
<link rel="service-desc" type="application/openapi+json" href="/openapi.json" />
138+
<link rel="service-doc" type="text/html" href="/api-docs" />
139+
<script
140+
type="application/ld+json"
141+
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
142+
/>
94143
<Script
95144
strategy="afterInteractive"
96145
src={`https://www.googletagmanager.com/gtag/js?id=${process.env.NEXT_PUBLIC_GA_ID}`}

app/llms-full.txt/route.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { NextResponse } from 'next/server'
2+
3+
export function GET() {
4+
const body = `# Dev Weekends - Extended LLM Index
5+
6+
## Organization
7+
Name: Dev Weekends
8+
Website: https://devweekends.com
9+
Description: Community-driven software engineering education through weekend sessions, mentorship, project building, and tech initiatives.
10+
11+
## Public Website URLs
12+
- https://devweekends.com/
13+
- https://devweekends.com/about
14+
- https://devweekends.com/our-story
15+
- https://devweekends.com/community
16+
- https://devweekends.com/sessions
17+
- https://devweekends.com/projects
18+
- https://devweekends.com/mentorship
19+
- https://devweekends.com/mentor
20+
- https://devweekends.com/testimonials
21+
- https://devweekends.com/careers
22+
- https://devweekends.com/ambassadors
23+
- https://devweekends.com/ambassador-program
24+
- https://devweekends.com/fellowship
25+
- https://devweekends.com/network
26+
- https://devweekends.com/mindmaster
27+
28+
## Program URLs
29+
- https://devweekends.com/dsoc
30+
- https://devweekends.com/dsoc/projects
31+
- https://devweekends.com/dsoc/register
32+
33+
## Discovery and Interoperability
34+
- robots.txt: https://devweekends.com/robots.txt
35+
- sitemap.xml: https://devweekends.com/sitemap.xml
36+
- llms.txt: https://devweekends.com/llms.txt
37+
- API Catalog: https://devweekends.com/.well-known/api-catalog
38+
- OpenAPI: https://devweekends.com/openapi.json
39+
- API Documentation: https://devweekends.com/api-docs
40+
- API Health: https://devweekends.com/api/health
41+
- Agent Skills Index: https://devweekends.com/.well-known/agent-skills/index.json
42+
43+
## AI Preferences
44+
Content-Signal: ai-train=no, search=yes, ai-input=no
45+
`
46+
47+
return new NextResponse(body, {
48+
headers: {
49+
'Content-Type': 'text/plain; charset=utf-8',
50+
},
51+
})
52+
}

app/llms.txt/route.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { NextResponse } from 'next/server'
2+
3+
export function GET() {
4+
const body = `# Dev Weekends
5+
> Dev Weekends is a learning community for software engineers with events, mentorship, projects, and career growth programs.
6+
7+
Canonical: https://devweekends.com
8+
Sitemap: https://devweekends.com/sitemap.xml
9+
Robots: https://devweekends.com/robots.txt
10+
11+
## Primary Pages
12+
- Home: https://devweekends.com/
13+
- About: https://devweekends.com/about
14+
- Sessions: https://devweekends.com/sessions
15+
- Community: https://devweekends.com/community
16+
- Projects: https://devweekends.com/projects
17+
- Mentorship: https://devweekends.com/mentorship
18+
- Careers: https://devweekends.com/careers
19+
20+
## Machine-Readable Discovery
21+
- API Catalog (RFC 9727): https://devweekends.com/.well-known/api-catalog
22+
- OpenAPI: https://devweekends.com/openapi.json
23+
- API Health: https://devweekends.com/api/health
24+
- Agent Skills Index: https://devweekends.com/.well-known/agent-skills/index.json
25+
26+
## Content Preferences
27+
- Content-Signal: ai-train=no, search=yes, ai-input=no
28+
`
29+
30+
return new NextResponse(body, {
31+
headers: {
32+
'Content-Type': 'text/plain; charset=utf-8',
33+
},
34+
})
35+
}

app/openapi.json/route.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { NextRequest, NextResponse } from 'next/server'
2+
3+
export function GET(request: NextRequest) {
4+
const origin = request.nextUrl.origin
5+
6+
const spec = {
7+
openapi: '3.0.3',
8+
info: {
9+
title: 'Dev Weekends API',
10+
version: '1.0.0',
11+
description: 'Public API surface for Dev Weekends.',
12+
},
13+
servers: [
14+
{
15+
url: origin,
16+
},
17+
],
18+
paths: {
19+
'/api/health': {
20+
get: {
21+
summary: 'Health check',
22+
responses: {
23+
'200': {
24+
description: 'API is healthy',
25+
},
26+
},
27+
},
28+
},
29+
},
30+
}
31+
32+
return NextResponse.json(spec, {
33+
headers: {
34+
'Content-Type': 'application/openapi+json; charset=utf-8',
35+
},
36+
})
37+
}

0 commit comments

Comments
 (0)