URL analysée
https://www.rivalr.app/
Score AI-Ready
Passable
sur 100
Économie de tokens
Détail du score
Protocoles émergents
0 sur 3 détectésEndpoints well-known recherchés par les agents IA. Détecté signifie qu’un agent peut découvrir et se connecter automatiquement à votre service.
-
OAuth Discovery RFC 8414
/.well-known/oauth-authorization-server -
MCP Server Card Anthropic
/.well-known/mcp.json -
A2A Agent Card Google
/.well-known/agent.json
Votre page n’utilise pas d’éléments <article> ou <main>. Ces conteneurs sémantiques aident les AI agents à identifier la zone de contenu principal et à ignorer la navigation, les barres latérales et les pieds de page.
Comment implémenter
Ajoutez un élément <main> autour du contenu principal de votre page, et utilisez <article> pour les blocs de contenu autonomes comme les billets de blog ou les descriptions de produits.
La structure de vos titres présente des problèmes (niveaux sautés ou plusieurs balises h1). Une hiérarchie propre aide les AI agents à comprendre l’organisation du contenu.
Comment implémenter
Assurez-vous d’avoir exactement un <h1> par page et que les titres suivent un ordre séquentiel : h1 > h2 > h3. Ne sautez pas de niveaux (par ex. de h1 directement à h3).
Aucun sitemap trouvé. Un sitemap aide les AI agents à découvrir toutes les pages de votre site.
Comment implémenter
Créez un /sitemap.xml listant toutes vos pages publiques. La plupart des CMS peuvent le générer automatiquement.
Votre page repose fortement sur les éléments <div>. Les éléments sémantiques comme <section>, <nav>, <header>, <footer> et <aside> fournissent une structure significative pour les AI agents.
Comment implémenter
Remplacez les conteneurs <div> génériques par les éléments sémantiques appropriés. Utilisez <section> pour les groupes thématiques, <nav> pour la navigation, <header>/<footer> pour les en-têtes et pieds de page ou de section.
Votre site ne supporte pas Markdown for Agents. Ce standard Cloudflare permet aux agents IA de demander du contenu en format markdown, réduisant l'utilisation de tokens de ~80%.
Comment implémenter
Implémentez un ou plusieurs : (1) Répondre à Accept: text/markdown avec du contenu markdown. (2) Servir des URLs .md (ex : /page.md). (3) Ajouter des balises <link rel="alternate" type="text/markdown">. (4) Ajouter des en-têtes HTTP Link pour la découverte markdown.
Aucune URL canonique trouvée. Cela aide les AI agents à identifier la version préférée d’une page et à éviter le contenu dupliqué.
Comment implémenter
Ajoutez une balise <link rel="canonical" href="..."> pointant vers l’URL canonique de la page.
De nombreux éléments ont des attributs de style en ligne. Ils ajoutent du bruit pour les AI agents lors de l’extraction du contenu.
Comment implémenter
Déplacez tous les styles en ligne vers des classes CSS dans votre feuille de style. Utilisez des frameworks CSS utilitaires comme Tailwind si vous avez besoin de nombreux styles uniques.
Rivalr — Find Players & Join Activity Groups Near You
Téléversez ce fichier sous /index.md sur votre serveur pour que les AI agents puissent accéder à une version propre de votre page. Vous pouvez également configurer la négociation de contenu Accept: text/markdown pour le servir automatiquement.
Notre recommandation
# rivalr.app > Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed. ## Main - [Rivalr — Find Players & Join Activity Groups Near You](https://www.rivalr.app/): Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one…
Le llms.txt complet nécessite une analyse de tout le domaine (bientôt disponible)
Téléversez ce fichier vers https://www.rivalr.app/llms.txt à la racine de votre domaine. Les AI agents comme ChatGPT, Claude et Perplexity consultent ce fichier pour comprendre la structure de votre site.
Ce site possède déjà un fichier llms.txt.
Format non valide — doit commencer par un titre # et contenir du contenu significatif<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed." />
<!-- Open Graph -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://www.rivalr.app/" />
<meta property="og:title" content="Rivalr — Find Players & Join Activity Groups" />
<meta property="og:description" content="Connect with people for football, basketball, padel, concerts, dinners, hikes and more. Post open spots or join an existing group — no group chat needed." />
<meta property="og:image" content="https://www.rivalr.app/og-image.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Rivalr — Find Players & Join Activity Groups" />
<meta property="og:site_name" content="Rivalr" />
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Rivalr — Find Players & Join Activity Groups" />
<meta name="twitter:description" content="Connect with people for football, basketball, padel, concerts, dinners, hikes and more. Post open spots or join an existing group — no group chat needed." />
<meta name="twitter:image" content="https://www.rivalr.app/og-image.png" />
<title>Rivalr — Find Players & Join Activity Groups Near You</title>
<!-- Schema.org JSON-LD -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://www.rivalr.app/#organization",
"name": "Rivalr",
"url": "https://www.rivalr.app/",
"logo": {
"@type": "ImageObject",
"url": "https://www.rivalr.app/og-image.png",
"width": 1200,
"height": 630
},
"description": "Rivalr connects people for shared activities — football, basketball, padel, concerts, dinners, hikes and more."
},
{
"@type": "WebSite",
"@id": "https://www.rivalr.app/#website",
"url": "https://www.rivalr.app/",
"name": "Rivalr",
"publisher": { "@id": "https://www.rivalr.app/#organization" }
},
{
"@type": "SoftwareApplication",
"@id": "https://www.rivalr.app/#app",
"name": "Rivalr",
"operatingSystem": ["iOS", "Android"],
"applicationCategory": "SocialNetworkingApplication",
"description": "Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed.",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "EUR"
},
"url": "https://www.rivalr.app/"
}
]
}
</script>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,400&family=DM+Serif+Display:ital@0;1&display=swap" rel="stylesheet" />
<script type="module" crossorigin src="/assets/index-DekaQV6t.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Bv57ANoo.css">
</head>
<body style="background:#0B0F19;color:#F1F5F9">
<div id="root"></div>
<noscript>
<h1>Find Players & Join Activity Groups Near You</h1>
<p>Rivalr connects you with people for football, basketball, padel, tennis, concerts, dinners, hiking and more. Post open spots or join an existing group — no group chat needed.</p>
<nav aria-label="Activity pages">
<a href="/activities/football/athens/">Football in Athens</a>
<a href="/activities/basketball/athens/">Basketball in Athens</a>
<a href="/activities/padel/athens/">Padel in Athens</a>
<a href="/activities/tennis/athens/">Tennis in Athens</a>
<a href="/activities/concert/athens/">Concerts in Athens</a>
<a href="/activities/hiking/athens/">Hiking in Athens</a>
<a href="/activities/dinner/athens/">Dinner in Athens</a>
<a href="/activities/football/thessaloniki/">Football in Thessaloniki</a>
<a href="/activities/basketball/thessaloniki/">Basketball in Thessaloniki</a>
<a href="/activities/padel/thessaloniki/">Padel in Thessaloniki</a>
</nav>
</noscript>
<!-- WebMCP: expose Rivalr tools to AI agents via the browser -->
<script>
(function () {
if (!navigator.modelContext || typeof navigator.modelContext.registerTool !== 'function') return;
const ac = new AbortController();
const BASE = 'https://api.rivalr.app';
navigator.modelContext.registerTool({
name: 'rivalr_list_postings',
description: 'List open match postings and pickup game slots on Rivalr, optionally filtered by activity type, city, or date.',
inputSchema: {
type: 'object',
properties: {
activity: { type: 'string', description: 'Activity type, e.g. football, basketball, padel, tennis, concert, dinner, hiking' },
city: { type: 'string', description: 'City name, e.g. athens, thessaloniki' },
date: { type: 'string', format: 'date', description: 'ISO 8601 date to filter by' }
}
},
execute: async ({ activity, city, date } = {}) => {
const params = new URLSearchParams();
if (activity) params.set('activity', activity);
if (city) params.set('city', city);
if (date) params.set('date', date);
const res = await fetch(`${BASE}/postings?${params}`);
return res.json();
},
signal: ac.signal
});
navigator.modelContext.registerTool({
name: 'rivalr_get_posting',
description: 'Get full details about a specific Rivalr match posting including spots left, date, venue, and participants.',
inputSchema: {
type: 'object',
required: ['id'],
properties: {
id: { type: 'string', description: 'Match posting ID' }
}
},
execute: async ({ id }) => {
const res = await fetch(`${BASE}/postings/${encodeURIComponent(id)}`);
return res.json();
},
signal: ac.signal
});
navigator.modelContext.registerTool({
name: 'rivalr_list_venues',
description: 'List sports venues on Rivalr with location, supported activities, and availability.',
inputSchema: {
type: 'object',
properties: {
city: { type: 'string', description: 'City name to filter venues' },
activity: { type: 'string', description: 'Activity type supported by the venue' }
}
},
execute: async ({ city, activity } = {}) => {
const params = new URLSearchParams();
if (city) params.set('city', city);
if (activity) params.set('activity', activity);
const res = await fetch(`${BASE}/venues?${params}`);
return res.json();
},
signal: ac.signal
});
window.addEventListener('unload', () => ac.abort(), { once: true });
})();
</script>
</body>
</html>
HTML sémantique
Missing <article> and <main> elements
No headings found
0 semantic elements, 1 divs (ratio: 0%)
No images found
Avg div depth: 0.0, max: 0
Efficacité du contenu
100% token reduction (HTML→Markdown)
Content ratio: 43.1% (3395 content chars / 7876 HTML bytes)
1/30 elements with inline styles (3.3%)
HTML size: 8KB
Visibilité IA
llms.txt exists but appears empty or invalid
robots.txt exists
All major AI bots allowed
No sitemap found
Données structurées
JSON-LD found: Organization, WebSite, SoftwareApplication
All OG tags present
Meta description: 149 chars
No canonical URL
lang="en"
Accessibilité
Content available without JavaScript
Page size: 8KB
Main content starts at 49% of HTML
{
"url": "https://www.rivalr.app/",
"timestamp": 1778798510409,
"fetch": {
"mode": "simple",
"timeMs": 775,
"htmlSizeBytes": 7876,
"supportsMarkdown": true,
"markdownAgents": {
"contentNegotiation": true,
"mdUrl": {
"found": false,
"url": null
},
"linkTag": {
"found": false,
"url": null
},
"linkHeader": {
"found": false,
"url": null
},
"responseHeaders": {
"contentSignal": "ai-train=yes, search=yes, ai-input=yes",
"xMarkdownTokens": "486",
"vary": "Accept"
},
"frontmatter": {
"present": true,
"fields": [
"title",
"description",
"image"
],
"level": "enriched"
},
"level": "application"
},
"statusCode": 200
},
"extraction": {
"title": "Rivalr — Find Players & Join Activity Groups Near You",
"excerpt": "Find Players & Join Activity Groups Near You\n Rivalr connects you with people for football, basketball, padel, tennis, concerts, dinners, hiking and more. Post open spots or join an existing grou",
"byline": null,
"siteName": null,
"lang": "en",
"contentLength": 3395,
"metadata": {
"description": "Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed.",
"ogTitle": "Rivalr — Find Players & Join Activity Groups",
"ogDescription": "Connect with people for football, basketball, padel, concerts, dinners, hikes and more. Post open spots or join an existing group — no group chat needed.",
"ogImage": "https://www.rivalr.app/og-image.png",
"ogType": "website",
"canonical": null,
"lang": "en",
"schemas": [
{
"@type": "Organization",
"@id": "https://www.rivalr.app/#organization",
"name": "Rivalr",
"url": "https://www.rivalr.app/",
"logo": {
"@type": "ImageObject",
"url": "https://www.rivalr.app/og-image.png",
"width": 1200,
"height": 630
},
"description": "Rivalr connects people for shared activities — football, basketball, padel, concerts, dinners, hikes and more."
},
{
"@type": "WebSite",
"@id": "https://www.rivalr.app/#website",
"url": "https://www.rivalr.app/",
"name": "Rivalr",
"publisher": {
"@id": "https://www.rivalr.app/#organization"
}
},
{
"@type": "SoftwareApplication",
"@id": "https://www.rivalr.app/#app",
"name": "Rivalr",
"operatingSystem": [
"iOS",
"Android"
],
"applicationCategory": "SocialNetworkingApplication",
"description": "Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed.",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "EUR"
},
"url": "https://www.rivalr.app/"
}
],
"robotsMeta": null,
"author": null,
"generator": null,
"markdownAlternateHref": null
}
},
"markdown": "\n",
"fullPageMarkdown": "Rivalr — Find Players & Join Activity Groups Near You\n",
"markdownStats": {
"images": 0,
"links": 10,
"tables": 0,
"codeBlocks": 0,
"headings": 1
},
"tokens": {
"htmlTokens": 1936,
"markdownTokens": 1,
"reduction": 1935,
"reductionPercent": 100
},
"score": {
"score": 71,
"grade": "C",
"dimensions": {
"semanticHtml": {
"score": 35,
"weight": 20,
"grade": "F",
"checks": {
"uses_article_or_main": {
"score": 0,
"weight": 20,
"details": "Missing <article> and <main> elements"
},
"proper_heading_hierarchy": {
"score": 0,
"weight": 25,
"details": "No headings found"
},
"semantic_elements": {
"score": 0,
"weight": 20,
"details": "0 semantic elements, 1 divs (ratio: 0%)"
},
"meaningful_alt_texts": {
"score": 100,
"weight": 15,
"details": "No images found"
},
"low_div_nesting": {
"score": 100,
"weight": 20,
"details": "Avg div depth: 0.0, max: 0"
}
}
},
"contentEfficiency": {
"score": 93,
"weight": 25,
"grade": "A",
"checks": {
"token_reduction_ratio": {
"score": 100,
"weight": 40,
"details": "100% token reduction (HTML→Markdown)"
},
"content_to_noise_ratio": {
"score": 100,
"weight": 30,
"details": "Content ratio: 43.1% (3395 content chars / 7876 HTML bytes)"
},
"minimal_inline_styles": {
"score": 50,
"weight": 15,
"details": "1/30 elements with inline styles (3.3%)"
},
"reasonable_page_weight": {
"score": 100,
"weight": 15,
"details": "HTML size: 8KB"
}
}
},
"aiDiscoverability": {
"score": 61,
"weight": 25,
"grade": "C",
"checks": {
"has_llms_txt": {
"score": 50,
"weight": 20,
"details": "llms.txt exists but appears empty or invalid"
},
"has_robots_txt": {
"score": 100,
"weight": 10,
"details": "robots.txt exists"
},
"robots_allows_ai_bots": {
"score": 100,
"weight": 15,
"details": "All major AI bots allowed"
},
"has_sitemap": {
"score": 0,
"weight": 10,
"details": "No sitemap found"
},
"supports_markdown_negotiation": {
"score": 40,
"weight": 25,
"details": "Application level — Content negotiation"
},
"has_content_signals": {
"score": 80,
"weight": 20,
"details": "robots.txt: ai-train=no, search=yes, ai-input=no | Policy included"
}
}
},
"structuredData": {
"score": 85,
"weight": 15,
"grade": "B",
"checks": {
"has_schema_org": {
"score": 100,
"weight": 30,
"details": "JSON-LD found: Organization, WebSite, SoftwareApplication"
},
"has_open_graph": {
"score": 100,
"weight": 25,
"details": "All OG tags present"
},
"has_meta_description": {
"score": 100,
"weight": 20,
"details": "Meta description: 149 chars"
},
"has_canonical_url": {
"score": 0,
"weight": 15,
"details": "No canonical URL"
},
"has_lang_attribute": {
"score": 100,
"weight": 10,
"details": "lang=\"en\""
}
}
},
"accessibility": {
"score": 85,
"weight": 15,
"grade": "B",
"checks": {
"content_without_js": {
"score": 100,
"weight": 40,
"details": "Content available without JavaScript"
},
"reasonable_page_size": {
"score": 100,
"weight": 30,
"details": "Page size: 8KB"
},
"fast_content_position": {
"score": 50,
"weight": 30,
"details": "Main content starts at 49% of HTML"
}
}
}
}
},
"recommendations": [
{
"id": "add_article_main",
"priority": "critical",
"category": "semanticHtml",
"titleKey": "rec.add_article_main.title",
"descriptionKey": "rec.add_article_main.description",
"howToKey": "rec.add_article_main.howto",
"effort": "quick-win",
"estimatedImpact": 8,
"checkScore": 0,
"checkDetails": "Missing <article> and <main> elements"
},
{
"id": "fix_heading_hierarchy",
"priority": "critical",
"category": "semanticHtml",
"titleKey": "rec.fix_heading_hierarchy.title",
"descriptionKey": "rec.fix_heading_hierarchy.description",
"howToKey": "rec.fix_heading_hierarchy.howto",
"effort": "quick-win",
"estimatedImpact": 6,
"checkScore": 0,
"checkDetails": "No headings found"
},
{
"id": "add_sitemap",
"priority": "critical",
"category": "aiDiscoverability",
"titleKey": "rec.add_sitemap.title",
"descriptionKey": "rec.add_sitemap.description",
"howToKey": "rec.add_sitemap.howto",
"effort": "quick-win",
"estimatedImpact": 5,
"checkScore": 0,
"checkDetails": "No sitemap found"
},
{
"id": "add_semantic_elements",
"priority": "critical",
"category": "semanticHtml",
"titleKey": "rec.add_semantic_elements.title",
"descriptionKey": "rec.add_semantic_elements.description",
"howToKey": "rec.add_semantic_elements.howto",
"effort": "moderate",
"estimatedImpact": 5,
"checkScore": 0,
"checkDetails": "0 semantic elements, 1 divs (ratio: 0%)"
},
{
"id": "add_markdown_negotiation",
"priority": "high",
"category": "aiDiscoverability",
"titleKey": "rec.add_markdown_negotiation.title",
"descriptionKey": "rec.add_markdown_negotiation.description",
"howToKey": "rec.add_markdown_negotiation.howto",
"effort": "significant",
"estimatedImpact": 6,
"checkScore": 40,
"checkDetails": "Application level — Content negotiation"
},
{
"id": "add_canonical_url",
"priority": "high",
"category": "structuredData",
"titleKey": "rec.add_canonical_url.title",
"descriptionKey": "rec.add_canonical_url.description",
"howToKey": "rec.add_canonical_url.howto",
"effort": "quick-win",
"estimatedImpact": 3,
"checkScore": 0,
"checkDetails": "No canonical URL"
},
{
"id": "remove_inline_styles",
"priority": "medium",
"category": "contentEfficiency",
"titleKey": "rec.remove_inline_styles.title",
"descriptionKey": "rec.remove_inline_styles.description",
"howToKey": "rec.remove_inline_styles.howto",
"effort": "moderate",
"estimatedImpact": 3,
"checkScore": 50,
"checkDetails": "1/30 elements with inline styles (3.3%)"
}
],
"llmsTxtPreview": "# rivalr.app\n\n> Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed.\n\n## Main\n- [Rivalr — Find Players & Join Activity Groups Near You](https://www.rivalr.app/): Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one…\n\n",
"llmsTxtExisting": "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta name=\"description\" content=\"Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed.\" />\n\n <!-- Open Graph -->\n <meta property=\"og:type\" content=\"website\" />\n <meta property=\"og:url\" content=\"https://www.rivalr.app/\" />\n <meta property=\"og:title\" content=\"Rivalr — Find Players & Join Activity Groups\" />\n <meta property=\"og:description\" content=\"Connect with people for football, basketball, padel, concerts, dinners, hikes and more. Post open spots or join an existing group — no group chat needed.\" />\n <meta property=\"og:image\" content=\"https://www.rivalr.app/og-image.png\" />\n <meta property=\"og:image:width\" content=\"1200\" />\n <meta property=\"og:image:height\" content=\"630\" />\n <meta property=\"og:image:alt\" content=\"Rivalr — Find Players & Join Activity Groups\" />\n <meta property=\"og:site_name\" content=\"Rivalr\" />\n\n <!-- Twitter Card -->\n <meta name=\"twitter:card\" content=\"summary_large_image\" />\n <meta name=\"twitter:title\" content=\"Rivalr — Find Players & Join Activity Groups\" />\n <meta name=\"twitter:description\" content=\"Connect with people for football, basketball, padel, concerts, dinners, hikes and more. Post open spots or join an existing group — no group chat needed.\" />\n <meta name=\"twitter:image\" content=\"https://www.rivalr.app/og-image.png\" />\n\n <title>Rivalr — Find Players & Join Activity Groups Near You</title>\n\n <!-- Schema.org JSON-LD -->\n <script type=\"application/ld+json\">\n {\n \"@context\": \"https://schema.org\",\n \"@graph\": [\n {\n \"@type\": \"Organization\",\n \"@id\": \"https://www.rivalr.app/#organization\",\n \"name\": \"Rivalr\",\n \"url\": \"https://www.rivalr.app/\",\n \"logo\": {\n \"@type\": \"ImageObject\",\n \"url\": \"https://www.rivalr.app/og-image.png\",\n \"width\": 1200,\n \"height\": 630\n },\n \"description\": \"Rivalr connects people for shared activities — football, basketball, padel, concerts, dinners, hikes and more.\"\n },\n {\n \"@type\": \"WebSite\",\n \"@id\": \"https://www.rivalr.app/#website\",\n \"url\": \"https://www.rivalr.app/\",\n \"name\": \"Rivalr\",\n \"publisher\": { \"@id\": \"https://www.rivalr.app/#organization\" }\n },\n {\n \"@type\": \"SoftwareApplication\",\n \"@id\": \"https://www.rivalr.app/#app\",\n \"name\": \"Rivalr\",\n \"operatingSystem\": [\"iOS\", \"Android\"],\n \"applicationCategory\": \"SocialNetworkingApplication\",\n \"description\": \"Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed.\",\n \"offers\": {\n \"@type\": \"Offer\",\n \"price\": \"0\",\n \"priceCurrency\": \"EUR\"\n },\n \"url\": \"https://www.rivalr.app/\"\n }\n ]\n }\n </script>\n\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n <link href=\"https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,400&family=DM+Serif+Display:ital@0;1&display=swap\" rel=\"stylesheet\" />\n <script type=\"module\" crossorigin src=\"/assets/index-DekaQV6t.js\"></script>\n <link rel=\"stylesheet\" crossorigin href=\"/assets/index-Bv57ANoo.css\">\n </head>\n <body style=\"background:#0B0F19;color:#F1F5F9\">\n <div id=\"root\"></div>\n <noscript>\n <h1>Find Players & Join Activity Groups Near You</h1>\n <p>Rivalr connects you with people for football, basketball, padel, tennis, concerts, dinners, hiking and more. Post open spots or join an existing group — no group chat needed.</p>\n <nav aria-label=\"Activity pages\">\n <a href=\"/activities/football/athens/\">Football in Athens</a>\n <a href=\"/activities/basketball/athens/\">Basketball in Athens</a>\n <a href=\"/activities/padel/athens/\">Padel in Athens</a>\n <a href=\"/activities/tennis/athens/\">Tennis in Athens</a>\n <a href=\"/activities/concert/athens/\">Concerts in Athens</a>\n <a href=\"/activities/hiking/athens/\">Hiking in Athens</a>\n <a href=\"/activities/dinner/athens/\">Dinner in Athens</a>\n <a href=\"/activities/football/thessaloniki/\">Football in Thessaloniki</a>\n <a href=\"/activities/basketball/thessaloniki/\">Basketball in Thessaloniki</a>\n <a href=\"/activities/padel/thessaloniki/\">Padel in Thessaloniki</a>\n </nav>\n </noscript>\n <!-- WebMCP: expose Rivalr tools to AI agents via the browser -->\n <script>\n (function () {\n if (!navigator.modelContext || typeof navigator.modelContext.registerTool !== 'function') return;\n const ac = new AbortController();\n const BASE = 'https://api.rivalr.app';\n\n navigator.modelContext.registerTool({\n name: 'rivalr_list_postings',\n description: 'List open match postings and pickup game slots on Rivalr, optionally filtered by activity type, city, or date.',\n inputSchema: {\n type: 'object',\n properties: {\n activity: { type: 'string', description: 'Activity type, e.g. football, basketball, padel, tennis, concert, dinner, hiking' },\n city: { type: 'string', description: 'City name, e.g. athens, thessaloniki' },\n date: { type: 'string', format: 'date', description: 'ISO 8601 date to filter by' }\n }\n },\n execute: async ({ activity, city, date } = {}) => {\n const params = new URLSearchParams();\n if (activity) params.set('activity', activity);\n if (city) params.set('city', city);\n if (date) params.set('date', date);\n const res = await fetch(`${BASE}/postings?${params}`);\n return res.json();\n },\n signal: ac.signal\n });\n\n navigator.modelContext.registerTool({\n name: 'rivalr_get_posting',\n description: 'Get full details about a specific Rivalr match posting including spots left, date, venue, and participants.',\n inputSchema: {\n type: 'object',\n required: ['id'],\n properties: {\n id: { type: 'string', description: 'Match posting ID' }\n }\n },\n execute: async ({ id }) => {\n const res = await fetch(`${BASE}/postings/${encodeURIComponent(id)}`);\n return res.json();\n },\n signal: ac.signal\n });\n\n navigator.modelContext.registerTool({\n name: 'rivalr_list_venues',\n description: 'List sports venues on Rivalr with location, supported activities, and availability.',\n inputSchema: {\n type: 'object',\n properties: {\n city: { type: 'string', description: 'City name to filter venues' },\n activity: { type: 'string', description: 'Activity type supported by the venue' }\n }\n },\n execute: async ({ city, activity } = {}) => {\n const params = new URLSearchParams();\n if (city) params.set('city', city);\n if (activity) params.set('activity', activity);\n const res = await fetch(`${BASE}/venues?${params}`);\n return res.json();\n },\n signal: ac.signal\n });\n\n window.addEventListener('unload', () => ac.abort(), { once: true });\n })();\n </script>\n </body>\n</html>",
"emergingProtocols": {
"oauthDiscovery": {
"exists": false,
"url": "https://www.rivalr.app/.well-known/oauth-authorization-server"
},
"mcpServerCard": {
"exists": false,
"url": "https://www.rivalr.app/.well-known/mcp.json"
},
"a2aAgentCard": {
"exists": false,
"url": "https://www.rivalr.app/.well-known/agent.json"
},
"count": 0
},
"snippets": [
{
"id": "fix_heading_hierarchy",
"title": "Fix heading hierarchy",
"description": "Your page has no <h1>. Every page needs exactly one <h1> as the main heading. Add it inside your <main> or <article>.",
"language": "html",
"code": "<h1>Rivalr — Find Players & Join Activity Groups Near You</h1>",
"filename": "<main> or <article>"
},
{
"id": "add_canonical_url",
"title": "Add canonical URL",
"description": "The canonical URL tells AI agents which version of the page is the \"official\" one, avoiding duplicate content issues.",
"language": "html",
"code": "<link rel=\"canonical\" href=\"https://www.rivalr.app/\">",
"filename": "<head>"
},
{
"id": "add_sitemap",
"title": "Create /sitemap.xml",
"description": "A sitemap helps AI agents discover all your pages. Most CMS platforms generate one automatically.",
"language": "xml",
"code": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n <url>\n <loc>https://www.rivalr.app/</loc>\n <lastmod>2026-05-14</lastmod>\n </url>\n</urlset>",
"filename": "/sitemap.xml"
},
{
"id": "add_article_main",
"title": "Wrap content in <main> and <article>",
"description": "Semantic HTML landmarks help AI agents identify the main content of your page.",
"language": "html",
"code": "<main>\n <article>\n <h1>Your Page Title</h1>\n <p>Your content here...</p>\n </article>\n</main>",
"filename": "<body>"
},
{
"id": "add_markdown_negotiation",
"title": "Support Markdown for Agents",
"description": "Let AI agents request a clean Markdown version of any page via content negotiation, .md alternate URLs, link tags or Link headers.",
"language": "html",
"code": "<!-- Mechanism 3: link tag advertising the .md alternate -->\n<link rel=\"alternate\" type=\"text/markdown\" href=\"/page.md\">",
"filename": "<head>",
"stacks": [
{
"id": "html",
"label": "HTML <head>",
"language": "html",
"filename": "<head>",
"code": "<!-- Mechanism 3: link tag advertising the .md alternate -->\n<link rel=\"alternate\" type=\"text/markdown\" href=\"/page.md\">"
},
{
"id": "express",
"label": "Express",
"language": "javascript",
"filename": "server.js",
"code": "// Mechanisms 1 + 4: content negotiation + Link header\napp.get('/page', (req, res) => {\n res.setHeader('Vary', 'Accept');\n res.setHeader('Link', '</page.md>; rel=\"alternate\"; type=\"text/markdown\"');\n if ((req.headers.accept || '').includes('text/markdown')) {\n res.type('text/markdown; charset=utf-8');\n return res.send(renderMarkdown('page'));\n }\n res.render('page');\n});"
},
{
"id": "fastify",
"label": "Fastify",
"language": "javascript",
"filename": "server.js",
"code": "// Mechanisms 1 + 4: content negotiation + Link header\nfastify.get('/page', async (req, reply) => {\n reply.header('Vary', 'Accept');\n reply.header('Link', '</page.md>; rel=\"alternate\"; type=\"text/markdown\"');\n if ((req.headers.accept || '').includes('text/markdown')) {\n return reply.type('text/markdown; charset=utf-8').send(renderMarkdown('page'));\n }\n return reply.view('/page.ejs');\n});"
},
{
"id": "nextjs",
"label": "Next.js",
"language": "typescript",
"filename": "app/page/route.ts",
"code": "// Next.js App Router — Route Handler returning Markdown\nimport { NextRequest } from 'next/server';\nimport { renderMarkdown } from '@/lib/md';\nexport async function GET(req: NextRequest) {\n const accept = req.headers.get('accept') || '';\n if (accept.includes('text/markdown')) {\n return new Response(await renderMarkdown('page'), {\n headers: {\n 'Content-Type': 'text/markdown; charset=utf-8',\n 'Vary': 'Accept',\n },\n });\n }\n // Fall through to the page component\n return new Response(null, { status: 404 });\n}"
},
{
"id": "wordpress",
"label": "WordPress",
"language": "php",
"filename": "functions.php",
"code": "<?php\n// Mechanism 1: respond to Accept: text/markdown on the same URL\nadd_action('template_redirect', function () {\n if (!is_singular()) return;\n $accept = $_SERVER['HTTP_ACCEPT'] ?? '';\n if (strpos($accept, 'text/markdown') === false) return;\n header('Content-Type: text/markdown; charset=utf-8');\n header('Vary: Accept');\n $post = get_queried_object();\n echo \"# \" . get_the_title($post) . \"\\n\\n\";\n echo wp_strip_all_tags(apply_filters('the_content', $post->post_content));\n exit;\n});"
},
{
"id": "static",
"label": "Hugo / Jekyll / Astro",
"language": "txt",
"filename": "static/page.md",
"code": "# Mechanism 2: serve .md alongside .html\n# Hugo: place page.md in /static/ — built unchanged\n# Jekyll: drop page.md in /assets/ — copied as-is\n# Astro: src/pages/page.md.ts that exports a GET returning markdown\n\n# Then advertise with mechanism 3 in <head>:\n# <link rel=\"alternate\" type=\"text/markdown\" href=\"/page.md\">"
}
]
}
]
}
Utilisez notre API pour obtenir ceci de manière programmatique (bientôt disponible)
Ce JSON est à usage interne — contrairement au Markdown et au llms.txt, il n’est pas destiné à être téléversé sur votre site. Conservez-le comme référence pour suivre l’évolution de votre score, partagez-le avec votre équipe de développement ou intégrez-le dans votre pipeline CI/CD.
Intégrez votre badge
Ajoutez ce badge à votre site. Il se met à jour automatiquement lorsque votre score de préparation à l’IA change.
<script src="https://agentready.md/badge.js" data-id="869e97d4-81ec-4e34-948b-49149a42d94e" data-domain="www.rivalr.app"></script>
[](https://agentready.md/fr/r/869e97d4-81ec-4e34-948b-49149a42d94e)
Bientôt : Analyse de domaine complet
Explorez l’ensemble de votre domaine, générez un llms.txt et surveillez votre score de préparation IA dans le temps. Rejoignez la liste d’attente pour être informé.