I have to create a podcast website for someone, they have like 100+ episodes.

How can I create a separate page for each episode? I don't want to make 100s of pages manually. Is there any ez way?
11 Replies
Chris Bolson
Chris Bolson13mo ago
Something like Astro would be perfect for this.
13eck
13eck13mo ago
* A static site generator that uses a template to generate each would work. Each time a new episode is made the SSG makes a new page * Make one /episode page that's an episode template and use a query param to decide what page info to fetch and display (/episode?no=38) * A server-side render backend could do the same as an SSG, but it makes the server do work on each HTTP call, and since podcast episodes aren't very dynamic it's kind of a waste
JOY
JOY12mo ago
Thanks 👍 Can astro do that?
13eck
13eck12mo ago
I believe Astro can, yes
Senra
Senra12mo ago
How can it be implemented in astro? I have not used astro as much, so I am unaware of the process of creating something that acts as a component and fetched data from external sources and sets them dynamically over many pages with astro.
b1mind
b1mind12mo ago
https://docs.astro.build/en/core-concepts/routing/#dynamic-routes you would do it the same as any other "blog" style component layout url params/query strings are teh way browsers have worked for A LONG time and frameworks* like Astro/SvelteKit leverage them really well.. Dynamic routes are great for this. Personally I like how SvelteKit exposes/uses them better but both work really similar.
JOY
JOY12mo ago
IM halfway making a project im making a podcast website for someone- i cant figure out the templating and dynamic routing I have an index page listing some episodes and when clicked on it i want to open the template with episode-specific info episodeList.astro
---
import Layout from '../layouts/Layout.astro';
import Navbar from '../components/Navbar.astro';
import { main } from '../utils/app.js';
import Card from '../components/Card.astro';
import EpisodeCard from '../components/EpisodeCard.astro';

const episodes = await main();
---


<Layout title="Episodes" >
<div class="bg-slate-900">
<Navbar />

<h1 class="text-white">this is good</h1>
<div class="text-white">
{episodes.map(episode => (
<EpisodeCard
href={`/episodes/${episode.id}`}
title={episode.name} body='body'
img={episode.images[0].url}/>
))
}

---
import Layout from '../layouts/Layout.astro';
import Navbar from '../components/Navbar.astro';
import { main } from '../utils/app.js';
import Card from '../components/Card.astro';
import EpisodeCard from '../components/EpisodeCard.astro';

const episodes = await main();
---


<Layout title="Episodes" >
<div class="bg-slate-900">
<Navbar />

<h1 class="text-white">this is good</h1>
<div class="text-white">
{episodes.map(episode => (
<EpisodeCard
href={`/episodes/${episode.id}`}
title={episode.name} body='body'
img={episode.images[0].url}/>
))
}

[slug].astro
---
import Layout from '../../layouts/Layout.astro';
const { slug } = Astro.params;

import { main, mainWithEpId } from '../../utils/app.js';
const episode = await mainWithEpId(slug);

// let res = await fetch(`https://api.spotify.com/v1/episodes/${slug}`)
// let episode = await res.json();

// The getStaticPaths() is required for static Astro sites.
// If using SSR, you will not need this function.
export async function getStaticPaths() {
// let data = await fetch(`https://api.spotify.com/v1/shows/1kRdGSsgqVpKmQJ4PWXhh3/episodes`)
// let episodes = await data.json();
let episodes = await main();
return episodes.map((episode) => ({
params: { slug: episode.id },
props: { episode: episode },
}));
}
---
<Layout title={episode.title}>
<article>
<h1>{episode.title}</h1>
<p>{episode.description}</p>
</article>
</Layout>
---
import Layout from '../../layouts/Layout.astro';
const { slug } = Astro.params;

import { main, mainWithEpId } from '../../utils/app.js';
const episode = await mainWithEpId(slug);

// let res = await fetch(`https://api.spotify.com/v1/episodes/${slug}`)
// let episode = await res.json();

// The getStaticPaths() is required for static Astro sites.
// If using SSR, you will not need this function.
export async function getStaticPaths() {
// let data = await fetch(`https://api.spotify.com/v1/shows/1kRdGSsgqVpKmQJ4PWXhh3/episodes`)
// let episodes = await data.json();
let episodes = await main();
return episodes.map((episode) => ({
params: { slug: episode.id },
props: { episode: episode },
}));
}
---
<Layout title={episode.title}>
<article>
<h1>{episode.title}</h1>
<p>{episode.description}</p>
</article>
</Layout>
showing error 404 when clicked on an episode
Kevin Powell
Kevin Powell12mo ago
what folder is the [slug].astro inside of? Can you manually get to the individual episode pages by manually entering in the url for an episode?
JOY
JOY12mo ago
pages/episodes/[slug].astro
pages/episodes/[slug].astro
No I can't get to it
Kevin Powell
Kevin Powell12mo ago
can you console.log(episodes) in the frontmatter and see what it returns? (it'll be in your terminal, not the browser console)
JOY
JOY12mo ago
---
import Layout from '../../layouts/Layout.astro';

import { main, mainWithEpId } from '../../utils/app.js';
const { slug } = Astro.params;
const { episode } = Astro.props;

export async function getStaticPaths() {
const episodes = await main();
return episodes.map((episode) => ({
params: { slug: episode.id },
props: { episode },
}));
}
---
<Layout title={episode.name}>
<article>
<h1>{episode.name}</h1>
<p>{episode.description}</p>
<iframe src=`https://open.spotify.com/embed/episode/${episode.id}?utm_source=generator&theme=0`
width="100%" height="232" allowfullscreen=""
allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"></iframe>
</article>
</Layout>

---
import Layout from '../../layouts/Layout.astro';

import { main, mainWithEpId } from '../../utils/app.js';
const { slug } = Astro.params;
const { episode } = Astro.props;

export async function getStaticPaths() {
const episodes = await main();
return episodes.map((episode) => ({
params: { slug: episode.id },
props: { episode },
}));
}
---
<Layout title={episode.name}>
<article>
<h1>{episode.name}</h1>
<p>{episode.description}</p>
<iframe src=`https://open.spotify.com/embed/episode/${episode.id}?utm_source=generator&theme=0`
width="100%" height="232" allowfullscreen=""
allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"></iframe>
</article>
</Layout>

This code is working somehow. Thanks for the help tho this is the slug