Build a Hacker News Top Stories Demo with Next.js + GitHub Copilot in one hour

siddontang
4 min readJul 17, 2022

--

I am not a front-end engineer, and have rarely written Javascript/HTML/CSS codes in my developing experience. I think building a front end is too hard, even harder than building a distributed database like TiDB :-)

Recently, I met Next.js, as well as being attracted by its simplicity and easy-to-use. The first time that I have the urge to build a web site.

Below is my first learning experience of Next.js.

I am also a HN(Hacker News) lover, so the demo here is to list the top stories of HN, and show the detailed info of the selected top story. You can see the demo source here.

First, let ’s start to create a next app below:

yarn create next-app hn-topstories-demo

I also follow the guide to install Tailwind CSS for Next.js.

Get HN data

Then, we need to get the top stories from HN. Fortunately, HN has already pushed its data to the Firebase, so we can get its data easily through Hacker News Firebase API.

Create a `lib/api.js` file in the root of the project, and use the following way to get the top stories, so cool:

export function getItem(id) {
let story = fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`)
.then(res => res.json())
return story
}
export function getTopStoryIDs() {
return fetch('https://hacker-news.firebaseio.com/v0/topstories.json')
.then(res => res.json())
.then(res => res.slice(0, 30))
}
export async function getTopStories() {
let ids = await getTopStoryIDs()
return Promise.all(ids.map(id => getItem(id)))
}

Notice: nearly most of the codes are auto completed by GitHub Copilot.

Home — List HN Top Stories

In the main home page `pages/index.js`, we follow the guide Data Fetching: getStaticProps to get the top stories.

export async function getStaticProps() {
const stories = await getTopStories();
return {
props: {
stories,
},
};
}

Then we use a list to show the top stories one by one. Here we also need to create a `pages/stories/[id].js` file but now can leave it empty.

<ul>
{stories.map(story => (
<li>
<Link href={`/stories/${story.id}`}>
<a>{story.title}</a>
</Link>
</li>
))}
</ul>

I ignore the CSS style in the above sample code, the real result is below:

Nav to the Detailed Story

After building the main page, it is time to show the detailed story. Here we focus on getting all the comments of this story. If you use HN, you may know that each comment may contain some sub comments, to show all easily, I introduce a `level` concept to control comment indent in the page later, like below:

export async function getComments(story) {
if (story.kids === undefined) {
return []
}
return Promise.all(story.kids.map(id => getItem(id)))
}
export async function getAllComments(level, story) {
let comments = await getComments(story)
let arr = []
for (let i = 0; i < comments.length; i++) {
arr.push({
level: level,
...comments[i],
})
if (comments[i].kids !== undefined) {
arr = arr.concat(await getAllComments(level + 1, comments[i]))
}
}
return arr
}

Here, I still need to emphasize that nearly all the codes are written by GitHub Copilot, the magic thing for me is that when I typed `let arr = []`, the Copilot completed the following the codes, the only thing I needed to do is to change the logic of level, awesome :-)

const levelIndent = {
0: "",
1: "indent-4",
2: "indent-8",
3: "indent-12",
......
}
<ul>
{
comments.map(comment => (
<li className={`${levelIndent[comment.level]}`} >
<div dangerouslySetInnerHTML={{ __html: comment.text }}></div>
</li>
))
}
</ul>

The above example code shows how to use Tailwind CSS to control the indent of different comments. The real result looks like below:

Deploy to Vercel

Thing goes well, the final step is to deploy the demo online, here I use Vercel, very easily too.

You can have a try here: Hacker News Top Stories Demo

Epilogue

I am very shocked by the Next.js + Copilot, and I believe that using them can improve our efficiency a lot. For this demo, I really just spent less than one hour to build it because most of the codes are written by GitHub Copilot 😭

By the way, Vercel is awesome too, I really admire its user experience. I never read its guide but successfully deployed my demo online, so cool. I hope our product TiDB cloud can provide the same user experience soon.

This is my quick attempt to build a front-end application. As I said above, I am a database engineer, so the next time I will use Next.js + TiDB cloud to build a realtime insight demo.

--

--