If you are thinking about building your own landing page or personal portfolio which can show off all your works (your blog posts from Medium or your YouTube channel) to the world. Then, you may ask the solutions for this question “How to embed Medium RSS feed or YouTube RSS feed in my websites.” Luckily, I came with this solution for you in this tutorial. It is exciting for me to share it here, and I hope you are also excited. Okay, let’s get started!
What we will explore in this topic:
Technologies I am using for this tutorial:
First, assign your mediumRSSFeed variable to its string value (URL link) like this:
const mediumRssFeed = “https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/@YOUR_MEDIUM_PROFILE_NAME_HERE”
To check if this link is correct, you can copy this URL link with your Medium Profile Name to a blank browser, then hit Enter. If you can see the JSON objects, it means this link is correct. This should be shown like this:
Then, fetch your articles’ data as below:
const MAX_ARTICLES = 10;
const [articles, setArticles] = useState();
useEffect(() => {
const loadArticles = async () => {
fetch(mediumRssFeed, { headers: { Accept: “application/json” } })
.then((res) => res.json())
.then((data) => data.items.filter((item) => item.title.length > 0))
.then((newArticles) => newArticles.slice(0, MAX_ARTICLES))
.then((articles) => setArticles(articles))
.catch((error) => console.log(error));
};
loadArticles();
}, [MAX_ARTICLES]);
Because I used React Hook for this Demo, you can see that I make use of the useState() and useEffect() function to fetch this data. I set MAX_ARTICLES=10 to limit the number of articles shown on my page, but you can set it to a different number as you like. For the max-count over 10, you have to signup/login to rss2json to get the API key as they said, “Count of feed items to return, default is 10 (api_key is required to use this parameter).”
Then, the map() function will help to return each item in the array of articles, like this:
{articles
? articles.map((item) => (
<a
className="link"
href={item.link}
target="_blank"
rel="nofollow noopener noreferrer"
title={item.title}
aria-label={item.link}
key={item.link}
>
<Card className={classes.root}>
<CardActionArea>
<CardMedia
className={classes.media}
image={item.thumbnail}
title={item.title}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{item.title}
</Typography>
<Typography
variant="body2"
color="textSecondary"
component="p"
>
{parseDate(item.pubDate)}
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<FacebookShareButton url={item.link}>
<FacebookIcon size={32} round={true} />
</FacebookShareButton>
<Button size="small" color="primary">
Learn More
</Button>
</CardActions>
</Card>
</a>
))
: "no article shown"}
In this Demo, I used the helper function parseDate() for item.pubDate to format the date for it easier to read. I added this function in the file name util.js such as below:
export const parseDate = (date) => {
const year = date.substring(0, 4);
const month = date.substring(5, 7);
const day = date.substring(8, 10);
switch (month) {
case "01":
return day + " January " + year;
case "02":
return day + " February " + year;
case "03":
return day + " March " + year;
case "04":
return day + " April " + year;
case "05":
return day + " May " + year;
case "06":
return day + " June " + year;
case "07":
return day + " July " + year;
case "08":
return day + " August " + year;
case "09":
return day + " September " + year;
case "10":
return day + " October " + year;
case "11":
return day + " November " + year;
case "12":
return day + " December " + year;
default:
return "No publication date";
}
};
You can custom this format based on your need.
Now your articles will be shown on your page like this. See Demo here:
Similarly, I also used the same technology for the demo. The only different part here is the RSS Feed URL link. This data should look like the below structure:
const youtubeRssFeed= “https://api.rss2json.com/v1/api.json?rss_url=https://youtube.com/feeds/videos.xml?channel_id=YOUR_CHANNEL_ID_HERE”
You also can check if it is the correct link by following the above method. Then you can fetch your YouTube videos’ data as below:
const MAX_VIDEOS = 10;
const [videos, setVideos] = useState();
useEffect(() => {
const loadVideos = async () => {
fetch(youtubeRssFeed, { headers: { Accept: “application/json” } })
.then((res) => res.json())
.then((data) => data.items.filter((item) => item.title.length > 0))
.then((newVideos) => newVideos.slice(0, MAX_VIDEOS))
.then((videos) => setVideos(videos))
.catch((error) => console.log(error));
};
loadVideos();
}, [MAX_VIDEOS]);
Once again, I also set my MAX_VIDEOS=10 to limit the number of videos shown on my page. You can set it to another number based on your choice. For the max-count over 10, you have to signup/login to rss2json to get the API key as they said, “Count of feed items to return, default is 10 (api_key is required to use this parameter).”
Also, the map() function will help to return each item in the array of videos, like this:
{videos
? videos.map((item) => (
<a
className="link"
href={item.link}
target="_blank"
rel="nofollow noopener noreferrer"
title={item.title}
aria-label={item.link}
key={item.link}
>
<Card className={classes.root}>
<CardActionArea>
<CardMedia
className={classes.media}
image={item.thumbnail}
title={item.title}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{item.title}
</Typography>
<Typography
variant="body2"
color="textSecondary"
component="p"
>
{parseDate(item.pubDate)}
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<FacebookShareButton url={item.link}>
<FacebookIcon size={32} round={true} />
</FacebookShareButton>
<Button size="small" color="primary">
Learn More
</Button>
</CardActions>
</Card>
</a>
))
Now, your YouTube videos are embedded and shown similarly like this Demo:
Admire your work and enjoy!
That’s it for this short tutorial. I hope you found this useful. Let me know if you need further help on this. Thanks for reading, and have a fun day!
Also Published On: https://juninguyen.medium.com/