Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions packages/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@
/>
<meta name="theme-color" content="#000000" />

<title>Audius — Free Music Streaming for Artists, Labels &amp; Fans</title>
<link rel="canonical" href="https://audius.co/" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://audius.co/" />

<link rel="manifest" href="/manifest.json" />

<meta name="application-name" content="Audius" />
Expand Down Expand Up @@ -122,6 +127,45 @@
></script>
<!-- end Optimizely -->

<!-- GEO: Organization, WebSite, SoftwareApplication schema for AI engines -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://audius.co/#organization",
"name": "Audius",
"url": "https://audius.co",
"logo": "https://og.audius.co/default",
"sameAs": [
"https://twitter.com/audius",
"https://github.com/audiusproject",
"https://discord.gg/audius",
"https://instagram.com/audius"
],
"description": "Audius is a decentralized music streaming and sharing platform that puts power back into the hands of content creators."
},
{
"@type": "WebSite",
"@id": "https://audius.co/#website",
"url": "https://audius.co",
"name": "Audius",
"publisher": { "@id": "https://audius.co/#organization" },
"description": "Free music streaming for artists, labels, and fans. Stream and share music on the decentralized Audius platform."
},
{
"@type": "SoftwareApplication",
"name": "Audius",
"applicationCategory": "MusicApplication",
"operatingSystem": "Web, iOS, Android",
"offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" },
"description": "Free music streaming for artists, labels, and fans. Upload, stream, and share music on the decentralized Audius platform."
}
]
}
</script>

<!-- start Meta Pixel -->
<script async type="text/javascript">
!(function (f, b, e, v, n, t, s) {
Expand Down
8 changes: 8 additions & 0 deletions packages/web/public/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Audius is the reference client and developer gateway for the Open Audio Protocol—stream music, build apps, extend the catalog. A music streaming service and toolkit built on the [Open Audio Protocol](https://openaudio.org). Permissionless music, your ecosystem. The de facto standard for agentic music apps.

## For everyone: what is Audius?

Audius is **free music streaming for artists, labels, and fans**. Artists upload and share music, run remix contests, and grow their community. Labels showcase rosters and discover talent. Fans stream, support artists, and discover new music. No paywalls, no gatekeeping. For a consumer-facing overview and blog, see [blog.audius.co](https://blog.audius.co) and its [llms.txt](https://blog.audius.co/llms.txt).

**For AI agents and developers:** Start with [agents.md](https://audius.co/agents.md) for overview and developer paths. For SDK setup and code examples, see [skill.md](https://audius.co/skill.md). Everything here is a recommendation—use maximal creativity. Agentic apps use Audius.

## Start Here
Expand Down Expand Up @@ -32,6 +36,10 @@ Audius is the reference client and developer gateway for the Open Audio Protocol
- [Developer Discord](https://discord.com/invite/audius): Community, developers section.

Build something unexpected. Recommendations only—your creativity, your rules.

## Blog and long-form content

- [Blog](https://blog.audius.co): Product updates, artist stories, and guides. For AI-friendly navigation and post index, see [blog.audius.co/llms.txt](https://blog.audius.co/llms.txt).
- [Postman](https://www.postman.com/samgutentag/workspace/audius-devs/collection/17755266-71da9172-77a7-427f-8ab5-1ce58f929ff5): Explore the API.
- [Hedgehog](https://docs.audius.co/developers/guides/hedgehog): Client-side Ethereum wallet.
- [Subgraph](https://docs.audius.co/developers/guides/subgraph): The Graph for on-chain governance data.
28 changes: 28 additions & 0 deletions packages/web/public/sitemaps/default.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://audius.co/</loc>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://audius.co/trending</loc>
<changefreq>daily</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://audius.co/download</loc>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://audius.co/legal/terms-of-use</loc>
<changefreq>yearly</changefreq>
<priority>0.3</priority>
</url>
<url>
<loc>https://audius.co/legal/privacy-policy</loc>
<changefreq>yearly</changefreq>
<priority>0.3</priority>
</url>
</urlset>
18 changes: 10 additions & 8 deletions packages/web/src/components/meta-tags/MetaTags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,16 @@ export const MetaTags = (props: MetaTagsProps) => {
</Helmet>
) : null}

<Helmet encodeSpecialCharacters={false}>
<link
rel='alternate'
type='application/json+oembed'
href={`${env.AUDIUS_URL}/oembed?url=${canonicalUrl}&format=json`}
title={formattedTitle}
/>
</Helmet>
{canonicalUrl ? (
<Helmet encodeSpecialCharacters={false}>
<link
rel='alternate'
type='application/json+oembed'
href={`${env.AUDIUS_URL}/oembed?url=${canonicalUrl}&format=json`}
title={formattedTitle}
/>
</Helmet>
) : null}
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { useEffect, useState } from 'react'
import { ThemeProvider } from '@audius/harmony'

import { CookieBanner } from 'components/cookie-banner/CookieBanner'
import { MetaTags } from 'components/meta-tags/MetaTags'
import { dismissCookieBanner as dismissCookieBannerAction } from 'store/application/ui/cookieBanner/actions'
import { shouldShowCookieBanner, dismissCookieBanner } from 'utils/gdpr'

import styles from './LandingPage2026.module.css'
import { CreateFutureCTA } from './components/CreateFutureCTA'
import { FAQ2026 } from './components/FAQ2026'
import { FAQ2026, faqItems } from './components/FAQ2026'
import { FeaturedContests2026 } from './components/FeaturedContests2026'
import { Footer2026 } from './components/Footer2026'
import { GrowthStartsHere } from './components/GrowthStartsHere'
Expand Down Expand Up @@ -101,8 +102,28 @@ export const LandingPage2026 = (props: LandingPage2026Props) => {
return dismissCookieBannerAction()
}

const homepageUrl = 'https://audius.co'
const faqPageStructuredData = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: faqItems.map((item) => ({
'@type': 'Question',
name: item.question,
acceptedAnswer: {
'@type': 'Answer',
text: item.answer
}
}))
}

return (
<ThemeProvider theme='day'>
<MetaTags
title='Audius — Free Music Streaming for Artists, Labels & Fans'
description='Audius is a decentralized music streaming platform for artists, labels, and fans. Stream and share music, upload tracks, and grow your audience—free.'
canonicalUrl={`${homepageUrl}/`}
structuredData={faqPageStructuredData}
/>
<div
id='landing-page-2026'
className={styles.page}
Expand All @@ -111,12 +132,14 @@ export const LandingPage2026 = (props: LandingPage2026Props) => {
{showCookieBanner ? (
<CookieBanner isPlaying={false} dismiss={onDismissCookie} />
) : null}
<Nav2026
isMobile={isMobileOrNarrow}
isAuthenticated={props.isAuthenticated}
openNavScreen={props.openNavScreen}
setRenderPublicSite={props.setRenderPublicSite}
/>
<header>
<Nav2026
isMobile={isMobileOrNarrow}
isAuthenticated={props.isAuthenticated}
openNavScreen={props.openNavScreen}
setRenderPublicSite={props.setRenderPublicSite}
/>
</header>
<main className={styles.main}>
<Hero2026
isMobile={isMobileOrNarrow}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
cursor: pointer;
}

.faqItemWrapper {
width: 100%;
}

.faqItem {
width: 100%;
background: none;
Expand Down Expand Up @@ -136,6 +140,18 @@
overflow: hidden;
}

.faqContentClosed {
max-height: 0;
padding-top: 0;
padding-bottom: 0;
border-top-width: 0;
overflow: hidden;
}

.faqContentOpen {
/* expanded state uses default .faqContent */
}

.faqAnswer {
font-family: 'Urbanist', sans-serif;
font-weight: 400;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function ChevronDown({ className }: { className?: string }) {
)
}

const faqItems = [
export const faqItems = [
{
question: 'Who is Audius made for?',
answer: 'Audius is made for us, the people pushing music scenes forward.'
Expand Down Expand Up @@ -69,28 +69,49 @@ export const FAQ2026 = (_props: FAQ2026Props) => {
<h2 id='faq-heading' className={styles.headline}>
Frequently Asked Questions
</h2>
<div className={styles.faqList} role='list'>
<div
className={styles.faqList}
role='list'
itemScope
itemType='https://schema.org/FAQPage'
>
{faqItems.map((item, index) => {
const isOpen = openSet.has(index)
return (
<button
<div
key={index}
type='button'
className={styles.faqItem}
onClick={() => toggle(index)}
aria-expanded={isOpen}
className={styles.faqItemWrapper}
role='listitem'
itemScope
itemProp='mainEntity'
itemType='https://schema.org/Question'
>
<div className={styles.faqHeader}>
<p className={styles.faqQuestion}>{item.question}</p>
<ChevronDown className={styles.chevron} />
</div>
{isOpen ? (
<div className={styles.faqContent}>
<p className={styles.faqAnswer}>{item.answer}</p>
<button
type='button'
className={styles.faqItem}
onClick={() => toggle(index)}
aria-expanded={isOpen}
>
<div className={styles.faqHeader}>
<p className={styles.faqQuestion} itemProp='name'>
{item.question}
</p>
<ChevronDown className={styles.chevron} />
</div>
) : null}
</button>
</button>
{/* GEO: Answer always in DOM so crawlers/AI can index it; hidden via CSS when collapsed */}
<div
itemScope
itemProp='acceptedAnswer'
itemType='https://schema.org/Answer'
className={`${styles.faqContent} ${isOpen ? styles.faqContentOpen : styles.faqContentClosed}`}
aria-hidden={!isOpen}
>
<p className={styles.faqAnswer} itemProp='text'>
{item.answer}
</p>
</div>
</div>
)
})}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@
text-align: left;
}

.stats {
font-family: 'Urbanist', sans-serif;
font-weight: 500;
font-size: 20px;
line-height: 1.5;
color: rgba(255, 255, 255, 0.8);
margin: 0;
width: 100%;
text-align: left;
}

@media (max-width: 800px) {
.inner {
padding: 0 16px;
Expand All @@ -53,4 +64,8 @@
.body {
font-size: 18px;
}

.stats {
font-size: 16px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import styles from './MadeForUs.module.css'

const messages = {
headline: 'Audius is made for us.',
body: "Audius is for people pushing music scenes forward. It's a community-run platform built on connection, collaboration, and culture-led artist growth."
body: "Audius is for people pushing music scenes forward. It's a community-run platform built on connection, collaboration, and culture-led artist growth.",
stats:
'40,000+ monthly active artists, millions of tracks, free 320kbps streaming—no paywalls.'
}

type MadeForUsProps = {
Expand All @@ -17,6 +19,7 @@ export const MadeForUs = (_props: MadeForUsProps) => {
{messages.headline}
</h2>
<p className={styles.body}>{messages.body}</p>
<p className={styles.stats}>{messages.stats}</p>
</div>
</section>
)
Expand Down
33 changes: 20 additions & 13 deletions packages/web/src/ssr/metaTags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ export const createSeoDescription = (msg: string, userPage?: boolean) => {
return `${msg} | Stream tracks, albums, playlists on desktop and mobile`
}

// Get base public URL based on environment
const getPublicUrl = (): string => {
/**
* Get base public URL based on environment (used for canonical, og:url, etc.)
*/
export const getPublicUrl = (): string => {
const env = process.env.VITE_ENVIRONMENT || 'development'
switch (env) {
case 'production':
Expand Down Expand Up @@ -95,18 +97,23 @@ export const getExploreInfo = (type?: string): ExploreInfo => {
}

/**
* Default meta tag context
* Default meta tag context (homepage / landing)
* GEO: Title and canonical so AI engines and crawlers get strong signals.
*/
export const getDefaultContext = () => ({
title: 'Audius - Empowering Creators',
description:
'Audius is a music streaming and sharing platform that puts power back into the hands of content creators.',
ogDescription:
'Audius is a music streaming and sharing platform that puts power back into the hands of content creators.',
image: DEFAULT_IMAGE_URL,
imageAlt: 'The Audius Platform',
thumbnail: true
})
export const getDefaultContext = () => {
const publicUrl = getPublicUrl()
return {
title: 'Audius — Free Music Streaming for Artists, Labels & Fans',
description:
'Audius is a music streaming and sharing platform that puts power back into the hands of content creators.',
ogDescription:
'Audius is a music streaming and sharing platform that puts power back into the hands of content creators.',
canonicalUrl: `${publicUrl}/`,
image: DEFAULT_IMAGE_URL,
imageAlt: 'The Audius Platform',
thumbnail: true
}
}

/**
* Upload page meta tag context
Expand Down
Loading