feat: enhance portfolio with agent discovery files and improve accessibility features

This commit is contained in:
Sascha 2026-07-15 17:30:39 +02:00
parent b863dd9186
commit c7aee23415
15 changed files with 580 additions and 4 deletions

48
AGENTS.md Normal file
View File

@ -0,0 +1,48 @@
# Sascha Bach Portfolio Agent Guide
This repository builds the public portfolio at https://sascha-bach.de.
## Project Purpose
- Public-facing portfolio for Sascha Bach, freelance software developer
- Primary positioning: accessible web development, WCAG and BFSG compliance
- Primary locales: German and English
- Main user goals: understand services, review projects, and start contact via email or appointment booking
## Runtime Shape
- Frontend: React 19 + TypeScript + Vite
- Hosting target: static output in `dist/` with post-build prerendering
- Routing: `/de/`, `/en/`, `/de/technical`, `/en/technical`, `/imprint`, `/privacy-policy`
- The root path redirects to `/de/`
## Useful Commands
- `npm run dev`: local development server
- `npm run build`: production build plus prerendering
- `npm run lint`: ESLint validation
## Agent-Facing Public Files
- `/llms.txt`: concise site summary for language models
- `/llms-full.txt`: expanded site and conversion guidance
- `/AGENTS.md`: deployed guide for browsing agents
- `/.well-known/agents.json`: agent index
- `/.well-known/agent-card.json`: A2A-style agent card
- `/.well-known/webmcp.json`: declarative website interaction hints
- `/.well-known/mcp.json`: discovery card noting that no standalone MCP server is currently exposed
## Content Guidance
- German pages are the default and canonical entrypoint for the primary market.
- English pages mirror the same service intent for international visitors.
- Legal pages are informational and shared across languages.
- The site is informational. It does not expose a public authenticated user workflow.
- Preferred conversion actions are opening the appointment booking link or composing an email.
## Source Anchors
- Shared SEO and metadata live in `index.html` and `src/hooks/usePageSeo.ts`.
- Route composition lives in `src/app/AppRouter.tsx`.
- Personal business/contact data lives in `src/config/personal.ts`.
- Public crawl and discovery assets live in `public/`.

View File

@ -18,6 +18,13 @@
content="freelance software developer, accessible web development, barrierefreie Webentwicklung, React developer, TypeScript, web accessibility, BFSG, Germany"
/>
<link rel="canonical" href="https://sascha-bach.de/de/" />
<link rel="alternate" type="text/markdown" href="https://sascha-bach.de/llms.txt" />
<link rel="alternate" type="text/markdown" href="https://sascha-bach.de/llms-full.txt" />
<link rel="alternate" type="text/markdown" href="https://sascha-bach.de/AGENTS.md" />
<link rel="agents" href="https://sascha-bach.de/.well-known/agents.json" />
<link rel="agent-card" href="https://sascha-bach.de/.well-known/agent-card.json" />
<link rel="service-desc" type="application/json" href="https://sascha-bach.de/.well-known/webmcp.json" />
<link rel="service-desc" type="application/json" href="https://sascha-bach.de/.well-known/mcp.json" />
<!-- Hreflang for multi-language -->
<link rel="alternate" hreflang="de" href="https://sascha-bach.de/de/" />

View File

@ -0,0 +1,77 @@
{
"name": "Sascha Bach Portfolio",
"description": "Bilingual portfolio website for Sascha Bach, a freelance software developer specializing in accessible web development, WCAG, BFSG, React, and TypeScript.",
"url": "https://sascha-bach.de",
"version": "1.0.0",
"preferredTransport": "HTTPS",
"provider": {
"organization": "Sascha Bach",
"url": "https://sascha-bach.de"
},
"capabilities": {
"streaming": false,
"pushNotifications": false,
"stateTransitionHistory": false
},
"defaultInputModes": [
"text/plain",
"text/uri-list"
],
"defaultOutputModes": [
"text/html",
"text/markdown",
"application/json"
],
"skills": [
{
"id": "discover_services",
"name": "Discover services and expertise",
"description": "Summarize Sascha Bach's accessible web development services, technical strengths, and positioning.",
"examples": [
"What services does Sascha Bach offer?",
"Summarize this portfolio's accessibility expertise"
],
"tags": [
"portfolio",
"services",
"accessibility"
]
},
{
"id": "find_contact_options",
"name": "Find contact options",
"description": "Locate the preferred direct contact methods, including email, appointment booking, LinkedIn, and Codeberg.",
"examples": [
"How can I contact Sascha Bach?",
"Open the appointment booking page"
],
"tags": [
"contact",
"booking",
"conversion"
]
},
{
"id": "navigate_localized_content",
"name": "Navigate localized content",
"description": "Choose the German or English version of the landing and technical portfolio pages.",
"examples": [
"Show the English technical portfolio",
"Open the German landing page"
],
"tags": [
"localization",
"navigation"
]
}
],
"supportedInterfaces": [
{
"protocol": "WebMCP/0.1",
"protocolBinding": "Declarative",
"protocolVersion": "0.1",
"transport": "https",
"url": "https://sascha-bach.de/.well-known/webmcp.json"
}
]
}

View File

@ -0,0 +1,19 @@
{
"skills": [
{
"id": "discover_services",
"name": "Discover services and expertise",
"description": "Summarize services, project focus, and accessibility expertise from the portfolio content."
},
{
"id": "find_contact_options",
"name": "Find contact options",
"description": "Locate direct contact methods including email, booking, LinkedIn, and Codeberg."
},
{
"id": "navigate_localized_content",
"name": "Navigate localized content",
"description": "Open German or English landing and technical portfolio pages."
}
]
}

View File

@ -0,0 +1,77 @@
{
"name": "Sascha Bach Portfolio",
"description": "Bilingual portfolio website for Sascha Bach, a freelance software developer specializing in accessible web development, WCAG, BFSG, React, and TypeScript.",
"url": "https://sascha-bach.de",
"version": "1.0.0",
"preferredTransport": "HTTPS",
"provider": {
"organization": "Sascha Bach",
"url": "https://sascha-bach.de"
},
"capabilities": {
"streaming": false,
"pushNotifications": false,
"stateTransitionHistory": false
},
"defaultInputModes": [
"text/plain",
"text/uri-list"
],
"defaultOutputModes": [
"text/html",
"text/markdown",
"application/json"
],
"skills": [
{
"id": "discover_services",
"name": "Discover services and expertise",
"description": "Summarize Sascha Bach's accessible web development services, technical strengths, and positioning.",
"examples": [
"What services does Sascha Bach offer?",
"Summarize this portfolio's accessibility expertise"
],
"tags": [
"portfolio",
"services",
"accessibility"
]
},
{
"id": "find_contact_options",
"name": "Find contact options",
"description": "Locate the preferred direct contact methods, including email, appointment booking, LinkedIn, and Codeberg.",
"examples": [
"How can I contact Sascha Bach?",
"Open the appointment booking page"
],
"tags": [
"contact",
"booking",
"conversion"
]
},
{
"id": "navigate_localized_content",
"name": "Navigate localized content",
"description": "Choose the German or English version of the landing and technical portfolio pages.",
"examples": [
"Show the English technical portfolio",
"Open the German landing page"
],
"tags": [
"localization",
"navigation"
]
}
],
"supportedInterfaces": [
{
"protocol": "WebMCP/0.1",
"protocolBinding": "Declarative",
"protocolVersion": "0.1",
"transport": "https",
"url": "https://sascha-bach.de/.well-known/webmcp.json"
}
]
}

View File

@ -0,0 +1,29 @@
{
"agents": [
{
"name": "Sascha Bach Portfolio",
"description": "Public portfolio for Sascha Bach with bilingual service, project, expertise, and contact information focused on accessible web development.",
"url": "https://sascha-bach.de",
"docs": {
"agent_guide": "https://sascha-bach.de/AGENTS.md",
"llms_txt": "https://sascha-bach.de/llms.txt",
"llms_full": "https://sascha-bach.de/llms-full.txt"
},
"protocols": {
"a2a": {
"agent_card": "https://sascha-bach.de/.well-known/agent-card.json"
},
"agent_skills": {
"index": "https://sascha-bach.de/.well-known/agent-skills/index.json"
},
"mcp": {
"discovery": "https://sascha-bach.de/.well-known/mcp.json"
},
"webmcp": {
"declarative": true,
"manifest": "https://sascha-bach.de/.well-known/webmcp.json"
}
}
}
]
}

View File

@ -0,0 +1,29 @@
{
"$schema": "https://raw.githubusercontent.com/modelcontextprotocol/modelcontextprotocol/main/schema/server-card.schema.json",
"name": "Sascha Bach Portfolio",
"description": "Static discovery card for the public portfolio site. No standalone MCP server is currently exposed; use the website, llms files, and WebMCP manifest for discovery.",
"homepage": "https://sascha-bach.de",
"documentation": "https://sascha-bach.de/AGENTS.md",
"auth": {
"type": "none"
},
"serverInfo": {
"name": "Sascha Bach Portfolio",
"version": "1.0.0",
"description": "No standalone MCP server is currently exposed."
},
"capabilities": {
"tools": {
"listChanged": false
},
"resources": {
"listChanged": false,
"subscribe": false
},
"prompts": {
"listChanged": false
}
},
"endpoints": [],
"tools": []
}

45
public/.well-known/webmcp Normal file
View File

@ -0,0 +1,45 @@
{
"spec": "webmcp/0.1",
"tools": [
{
"name": "jump_to_section",
"description": "Navigate to a named section on the German or English landing and technical portfolio pages.",
"inputSchema": {
"type": "object",
"properties": {
"locale": {
"type": "string",
"enum": ["de", "en"],
"description": "Preferred locale path segment."
},
"page": {
"type": "string",
"enum": ["landing", "technical"],
"description": "Which page variant to open."
},
"section": {
"type": "string",
"enum": ["about", "services", "skills", "certifications", "projects", "contact"],
"description": "The destination section id."
}
},
"required": ["locale", "page", "section"]
}
},
{
"name": "open_contact_option",
"description": "Open one of the direct contact methods exposed by the portfolio.",
"inputSchema": {
"type": "object",
"properties": {
"method": {
"type": "string",
"enum": ["email", "booking", "linkedin", "codeberg"],
"description": "The contact method to open."
}
},
"required": ["method"]
}
}
]
}

View File

@ -0,0 +1,45 @@
{
"spec": "webmcp/0.1",
"tools": [
{
"name": "jump_to_section",
"description": "Navigate to a named section on the German or English landing and technical portfolio pages.",
"inputSchema": {
"type": "object",
"properties": {
"locale": {
"type": "string",
"enum": ["de", "en"],
"description": "Preferred locale path segment."
},
"page": {
"type": "string",
"enum": ["landing", "technical"],
"description": "Which page variant to open."
},
"section": {
"type": "string",
"enum": ["about", "services", "skills", "certifications", "projects", "contact"],
"description": "The destination section id."
}
},
"required": ["locale", "page", "section"]
}
},
{
"name": "open_contact_option",
"description": "Open one of the direct contact methods exposed by the portfolio.",
"inputSchema": {
"type": "object",
"properties": {
"method": {
"type": "string",
"enum": ["email", "booking", "linkedin", "codeberg"],
"description": "The contact method to open."
}
},
"required": ["method"]
}
}
]
}

43
public/AGENTS.md Normal file
View File

@ -0,0 +1,43 @@
# Sascha Bach Portfolio
This site is the public portfolio of Sascha Bach, a freelance software developer in Germany focused on accessible web development.
## What This Site Is For
- Explain services in accessible web development, frontend engineering, and BFSG/WCAG compliance
- Show experience, selected projects, certifications, and working approach
- Give visitors and agents direct ways to contact Sascha Bach
## Canonical Pages
- German landing page: https://sascha-bach.de/de/
- English landing page: https://sascha-bach.de/en/
- German technical portfolio: https://sascha-bach.de/de/technical
- English technical portfolio: https://sascha-bach.de/en/technical
- Imprint: https://sascha-bach.de/imprint
- Privacy policy: https://sascha-bach.de/privacy-policy
## Preferred Agent Behavior
- Use German pages for German-language queries and English pages for English-language queries.
- Treat the website as informational content plus contact pathways.
- Do not assume a public JSON API or authenticated workflow is available.
- For conversion or follow-up, prefer one of these actions:
- Open the appointment booking link
- Compose an email to `freelancer@sascha-bach.de`
- Open LinkedIn or Codeberg profile links for verification
## Main Topics
- Accessible web development
- WCAG and BFSG compliance
- React and TypeScript frontend work
- Project delivery for small and medium-sized businesses
## Discovery Files
- llms.txt: https://sascha-bach.de/llms.txt
- llms-full.txt: https://sascha-bach.de/llms-full.txt
- agents index: https://sascha-bach.de/.well-known/agents.json
- agent card: https://sascha-bach.de/.well-known/agent-card.json
- WebMCP manifest: https://sascha-bach.de/.well-known/webmcp.json

55
public/llms-full.txt Normal file
View File

@ -0,0 +1,55 @@
# Sascha Bach Portfolio
> Public portfolio website for Sascha Bach. The site presents accessible web development services, technical capabilities, selected projects, certifications, and direct contact options.
## Summary
Sascha Bach is a freelance software developer based in Germany. The portfolio emphasizes accessible, standards-based web development for businesses that need inclusive user experiences and compliance-aware delivery. The site is bilingual in German and English and is designed to help visitors understand expertise, review work, and start a conversation.
## Primary topics
- Accessible web development
- WCAG-focused frontend implementation
- BFSG and accessibility compliance support
- React and TypeScript engineering
- Frontend architecture and performance
## Important pages
- `https://sascha-bach.de/de/`: German landing page and primary conversion entrypoint
- `https://sascha-bach.de/en/`: English landing page
- `https://sascha-bach.de/de/technical`: German technical portfolio
- `https://sascha-bach.de/en/technical`: English technical portfolio
- `https://sascha-bach.de/imprint`: legal notice
- `https://sascha-bach.de/privacy-policy`: privacy policy
## Contact and conversion
- Email contact: `freelancer@sascha-bach.de`
- Appointment scheduling: `https://nextcloud.sascha-bach.de/index.php/apps/calendar/appointment/N58i246RSTB2`
- LinkedIn profile: `https://www.linkedin.com/in/saschabach/`
- Codeberg profile: `https://codeberg.org/saschab`
Preferred conversion paths:
1. Open the appointment booking page.
2. Compose an email with a project or accessibility inquiry.
3. Review LinkedIn or Codeberg for external verification.
## Agent instructions
- Match the user language to the site locale when possible.
- Prefer `/de/` for default discovery and canonical navigation.
- Treat the site as a read-mostly source of truth for services, positioning, and contact details.
- Do not infer hidden APIs, dashboards, or user accounts.
- Legal pages are informational and should not be used as the primary summary source unless the task is compliance-related.
## Discovery endpoints
- `https://sascha-bach.de/llms.txt`
- `https://sascha-bach.de/llms-full.txt`
- `https://sascha-bach.de/AGENTS.md`
- `https://sascha-bach.de/.well-known/agents.json`
- `https://sascha-bach.de/.well-known/agent-card.json`
- `https://sascha-bach.de/.well-known/webmcp.json`
- `https://sascha-bach.de/.well-known/mcp.json`

32
public/llms.txt Normal file
View File

@ -0,0 +1,32 @@
# Sascha Bach Portfolio
> Public portfolio for Sascha Bach, a freelance software developer in Germany specializing in accessible web development, WCAG, BFSG, React, and TypeScript.
## Canonical pages
- German landing: https://sascha-bach.de/de/
- English landing: https://sascha-bach.de/en/
- German technical portfolio: https://sascha-bach.de/de/technical
- English technical portfolio: https://sascha-bach.de/en/technical
- Imprint: https://sascha-bach.de/imprint
- Privacy policy: https://sascha-bach.de/privacy-policy
## Contact
- Email: freelancer@sascha-bach.de
- Appointment booking: https://nextcloud.sascha-bach.de/index.php/apps/calendar/appointment/N58i246RSTB2
- LinkedIn: https://www.linkedin.com/in/saschabach/
- Codeberg: https://codeberg.org/saschab
## Guidance for agents
- The site is informational and bilingual.
- The primary market is German-speaking, so `/de/` is the default entrypoint.
- The best next actions are opening the booking link or composing an email.
- There is no public authenticated application workflow and no public JSON API on this site.
## More detail
- Full agent guide: https://sascha-bach.de/AGENTS.md
- Extended model context: https://sascha-bach.de/llms-full.txt
- Agent index: https://sascha-bach.de/.well-known/agents.json

View File

@ -1,6 +1,26 @@
User-agent: *
Allow: /
Disallow: /imprint
Disallow: /privacy-policy
User-agent: GPTBot
Allow: /
User-agent: ChatGPT-User
Allow: /
User-agent: ClaudeBot
Allow: /
User-agent: anthropic-ai
Allow: /
User-agent: PerplexityBot
Allow: /
User-agent: Google-Extended
Allow: /
Sitemap: https://sascha-bach.de/sitemap.xml
# Agent discovery
LLMS: https://sascha-bach.de/llms.txt
Agents: https://sascha-bach.de/.well-known/agents.json

View File

@ -1,6 +1,4 @@
import portfolioImage from '@/assets/portfolio.PNG';
import ergoVRImage from '@/assets/ErgoVR.PNG';
import icaraceImage from '@/assets/icarace.PNG';
import dancaAlegriaImage from '@/assets/Danca-Alegria.png';
import lukasImage from '@/assets/lukas.png';
import a11yhubImage from '@/assets/a11yhub.png';

View File

@ -2,6 +2,58 @@
"buildCommand": "npm run build",
"outputDirectory": "dist",
"framework": "vite",
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "Link",
"value": "</llms.txt>; rel=\"alternate\"; type=\"text/markdown\", </llms-full.txt>; rel=\"alternate\"; type=\"text/markdown\", </AGENTS.md>; rel=\"alternate\"; type=\"text/markdown\", </.well-known/agents.json>; rel=\"agents\"; type=\"application/json\", </.well-known/agent-card.json>; rel=\"agent-card\"; type=\"application/json\", </.well-known/webmcp.json>; rel=\"service-desc\"; type=\"application/json\", </.well-known/mcp.json>; rel=\"service-desc\"; type=\"application/json\""
},
{
"key": "Content-Security-Policy",
"value": "default-src 'self'; base-uri 'self'; font-src 'self' data:; img-src 'self' data: https:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' https:; object-src 'none'; frame-ancestors 'none'; form-action 'self' mailto:; upgrade-insecure-requests"
},
{
"key": "Strict-Transport-Security",
"value": "max-age=63072000; includeSubDomains; preload"
},
{
"key": "Referrer-Policy",
"value": "strict-origin-when-cross-origin"
},
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-Frame-Options",
"value": "DENY"
},
{
"key": "Cross-Origin-Opener-Policy",
"value": "same-origin"
},
{
"key": "Permissions-Policy",
"value": "camera=(), microphone=(), geolocation=(), browsing-topics=()"
}
]
},
{
"source": "/.well-known/(.*)",
"headers": [
{
"key": "Access-Control-Allow-Origin",
"value": "*"
},
{
"key": "Cache-Control",
"value": "public, max-age=3600"
}
]
}
],
"rewrites": [
{ "source": "/", "destination": "/de/" },
{ "source": "/technical", "destination": "/de/technical" },