1<!DOCTYPE html> 2<html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 7 <!-- 8 Everything between the seo markers is rewritten per route at build time by 9 scripts/prerender-meta.mjs, and kept in sync on client-side navigation by 10 src/seo/index.ts. Both read src/seo/pages.json. The values below are the 11 homepage defaults, which also serve any route without its own entry. 12 Edit pages.json, not this block. 13 --> 14 <!-- seo:start --> 15 <title>Sporlyst â Multi-Sport Training Analytics</title> 16 <meta name="description" content="Sporlyst turns your training data into clear insight. Track load, fitness, form, and race readiness across every sport in one place. Now in beta."> 17 <link rel="canonical" href="https://sporlyst.com/"> 18 19 <meta property="og:type" content="website"> 20 <meta property="og:site_name" content="Sporlyst"> 21 <meta property="og:locale" content="en_US"> 22 <meta property="og:title" content="Sporlyst â Multi-Sport Training Analytics"> 23 <meta property="og:description" content="Sporlyst turns your training data into clear insight. Track load, fitness, form, and race readiness across every sport in one place. Now in beta."> 24 <meta property="og:url" content="https://sporlyst.com/"> 25 <meta property="og:image" content="https://sporlyst.com/og/og-default.png"> 26 <meta property="og:image:width" content="1200"> 27 <meta property="og:image:height" content="630"> 28 <meta property="og:image:alt" content="Sporlyst â Multi-Sport Training Analytics"> 29 30 <meta name="twitter:card" content="summary_large_image"> 31 <meta name="twitter:title" content="Sporlyst â Multi-Sport Training Analytics"> 32 <meta name="twitter:description" content="Sporlyst turns your training data into clear insight. Track load, fitness, form, and race readiness across every sport in one place. Now in beta."> 33 <meta name="twitter:image" content="https://sporlyst.com/og/og-default.png"> 34<!-- seo:end --> 35 36 <link rel="icon" href="/favicon.ico" sizes="any"> 37 <link rel="apple-touch-icon" href="/apple-touch-icon.png"> 38 <link rel="manifest" href="/site.webmanifest"> 39 <meta name="theme-color" content="#131313"> 40 <meta name="color-scheme" content="dark"> 41 <meta name="application-name" content="Sporlyst"> 42 <meta name="apple-mobile-web-app-title" content="Sporlyst"> 43 44 <!-- Fonts are served from this origin (public/fonts/), so loading a page 45 sends nothing to fonts.googleapis.com. The files and the stylesheet are 46 generated by `npm run fonts:sync` â see scripts/fonts/sync-fonts.mjs. 47 Preloaded: the two faces that paint on every route. Fugaz One is only 48 the wordmark, small enough to leave to normal discovery. `crossorigin` 49 is required even same-origin â fonts are always fetched in CORS mode, 50 and without it the preload is fetched a second time. --> 51 <link rel="preload" href="/fonts/lexend-latin.woff2" as="font" type="font/woff2" crossorigin> 52 <link rel="preload" href="/fonts/material-symbols-outlined.woff2" as="font" type="font/woff2" crossorigin> 53 <link rel="stylesheet" href="/fonts/fonts.css"> 54 55 <!-- Site-wide structured data. Present on every prerendered route, so search 56 engines and AI crawlers can identify the product without running JS. 57 58 `sameAs` on the Organization node is what tells Google that a social 59 profile and this site are one brand. It duplicates the URLs in 60 src/constants/links.ts, which the footer renders â this file is static 61 HTML and cannot import that module. Keep the two in sync, and keep 62 sameAs on this one Organization node rather than adding a second. --> 63
63<script type="application/ld+json"> 64 { 65 "@context": "https://schema.org", 66 "@graph": [ 67 { 68 "@type": "Organization", 69 "@id": "https://sporlyst.com/#organization", 70 "name": "Sporlyst", 71 "url": "https://sporlyst.com/", 72 "sameAs": ["https://www.instagram.com/sporlyst/"], 73 "logo": { 74 "@type": "ImageObject", 75 "url": "https://sporlyst.com/icon-512.png", 76 "width": 512, 77 "height": 512 78 }, 79 "description": "Sporlyst is an athletic performance platform that turns your training data into load, fitness, and form analytics for athletes.", 80 "contactPoint": { 81 "@type": "ContactPoint", 82 "contactType": "customer support", 83 "email": "[email protected]", 84 "url": "https://sporlyst.com/contact" 85 } 86 }, 87 { 88 "@type": "WebSite", 89 "@id": "https://sporlyst.com/#website", 90 "url": "https://sporlyst.com/", 91 "name": "Sporlyst", 92 "publisher": { "@id": "https://sporlyst.com/#organization" }, 93 "inLanguage": "en" 94 }, 95 { 96 "@type": "SoftwareApplication", 97 "@id": "https://sporlyst.com/#app", 98 "name": "Sporlyst", 99 "url": "https://sporlyst.com/", 100 "applicationCategory": "HealthApplication", 101 "applicationSubCategory": "Multi-sport training analytics", 102 "operatingSystem": "Web browser", 103 "publisher": { "@id": "https://sporlyst.com/#organization" }, 104 "description": "Automatically syncs training activities from the devices and services athletes already use, then tracks training load, fitness, fatigue, form, goals, and race readiness. Includes a coaching platform for structured workouts and athlete calendars.", 105 "featureList": [ 106 "Automatic activity sync from connected devices and services", 107 "Manual .fit and CSV import", 108 "Training load management: fitness, fatigue, and form", 109 "Historical performance analysis", 110 "Yearly training goals", 111 "Public athlete profiles", 112 "Coaching platform with structured workouts and athlete calendars", 113 "Live race tracking for organizers" 114 ], 115 "offers": { 116 "@type": "Offer", 117 "price": "0", 118 "priceCurrency": "EUR", 119 "description": "Free forever for athletes. Coaches pay for their roster.", 120 "url": "https://sporlyst.com/pricing" 121 } 122 } 123 ] 124 } 125 </script>
125 126
126<script type="module" crossorigin src="/assets/index-BWLfjhcL.js"></script>
126 127 <link rel="stylesheet" crossorigin href="/assets/index-CwfTLjsn.css"> 128 </head> 129 <body> 130 <div id="app"></div> 131 </body> 132</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.