mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-10-02 04:43:58 +00:00
feat(web): AEO foundation — robots, JSON-LD, meta, llms.txt, security headers
Implements the high-signal, content-independent fixes flagged across the multi-engine AEO audit: - robots.txt (app/robots.ts): allow mainstream + AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, …), disallow /api, link sitemap. - Organization + WebSite JSON-LD on the root layout; BlogPosting JSON-LD on /blog/[slug]. - Richer metadata: descriptive default title, Open Graph + Twitter cards, canonical, icons, metadataBase. - Per-route titles/descriptions for catch-all routes (docs, about, hire-us, agent-swarm, …) instead of the generic "LogicSRC". - /llms.txt (llmstxt.org) and /skill.md capability manifest. - /.well-known/security.txt (RFC 9116). - Security headers via next.config: HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy (CSP intentionally deferred to avoid breaking inline/stats/CoinPay scripts). Verified in a running build: all routes serve correctly and headers are set. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ce79f02211
commit
6518dfb4a9
8 changed files with 285 additions and 19 deletions
|
|
@ -14,13 +14,16 @@ type PostRow = {
|
|||
html: string;
|
||||
featured_image: { url?: string } | null;
|
||||
published_at: string;
|
||||
updated_at: string;
|
||||
};
|
||||
|
||||
const SITE_URL = (process.env.PUBLIC_URL ?? "https://logicsrc.com").replace(/\/$/, "");
|
||||
|
||||
async function loadPost(slug: string): Promise<PostRow | null> {
|
||||
const supabase = publicClient();
|
||||
const { data } = await supabase
|
||||
.from("blog_posts")
|
||||
.select("slug, title, excerpt, html, featured_image, published_at")
|
||||
.select("slug, title, excerpt, html, featured_image, published_at, updated_at")
|
||||
.eq("slug", slug)
|
||||
.eq("status", "published")
|
||||
.maybeSingle();
|
||||
|
|
@ -65,8 +68,25 @@ export default async function BlogPostPage({
|
|||
const post = await loadPost(slug);
|
||||
if (!post) notFound();
|
||||
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
headline: post.title,
|
||||
description: post.excerpt ?? undefined,
|
||||
image: post.featured_image?.url ? [post.featured_image.url] : undefined,
|
||||
datePublished: post.published_at,
|
||||
dateModified: post.updated_at,
|
||||
url: `${SITE_URL}/blog/${post.slug}`,
|
||||
mainEntityOfPage: `${SITE_URL}/blog/${post.slug}`,
|
||||
publisher: { "@id": `${SITE_URL}/#organization` },
|
||||
};
|
||||
|
||||
return (
|
||||
<SiteShell active="Blog">
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
||||
/>
|
||||
<article className="band" style={{ maxWidth: "48rem" }}>
|
||||
<p style={{ marginBottom: "1.5rem" }}>
|
||||
<Link href="/blog" style={{ color: "#5b6b7a", textDecoration: "none" }}>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue