Displaying Dev.to Articles on your Website using Next.js
Published: 2022-11-16 02:42:38

---
title: Displaying Dev.to Articles on your Website using Next.js
published: true
date: 2022-11-14 14:01:35 UTC
tags: 
canonical_url: https://cherylm.hashnode.dev/displaying-devto-articles-on-your-website-using-nextjs
---

> Github: https://github.com/cherylli/devto-api-nextjs
> 
> codesandbox: https://codesandbox.io/p/github/cherylli/devto-api-nextjs/main

We will create a basic app to pull articles from dev.to API, using [next.js static site generation (SSG)](https://nextjs.org/docs/basic-features/data-fetching/get-static-props) and display the article when clicked into it.

Dev.to API documentation can be found [here].(https://developers.forem.com/api)

The endpoint to retrieve all posts from a user is`https://dev.to/api/articles?username={username}`

where the username can be a personal account or an organisation account name.

For example, the api endpoint to fetch all my articles is https://dev.to/api/articles?username=cherylli

the result looks like this,

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/96vpg7cm1odb8ww7xot7.png)

Using SSG, we fetch all the posts in [getStaticProps()](https://nextjs.org/docs/basic-features/data-fetching/get-static-props),

```
//pages/index.js
export async function getStaticProps(){
    const res = await fetch('https://dev.to/api/articles?username=cherylli')
    const posts = await res.json()

    return{
        props:{
            posts
        },
      }
}

```

Props will be generate on build, passing the props into the page component, and display them on the page

```
//pages/index.js
const Home = ({posts}) => {
    return (
        <main className={styles.container}>
            <h1>
                Dev.to Blog
            </h1>
            <p>
                displaying dev.to blog posts using the Dev.to API
            </p>
            <div className={styles.grid}>
                {posts.map((post) => (
                    <BlogPostCard post={post} key={post.id}/>
                ))}
            </div>
        </main>)
}

```

![Index page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ef8reslmi0es2s6uy5cx.png)

# Single Article page

The article body is not included in the above endpoint. So we will need to use another endpoint to get the article content.

If a user also publishes to an organization, `https://dev.to/api/articles?username={username}` returns all articles (including any articles published to an organization by the user). We will then need to specify username or organization when using the single article endpoint `https://dev.to/api/articles/{username/organization}/{slug}`.

For example, this gets the article I published to the organization 'wdp'.

`https://dev.to/api/articles/wdp/using-google-fonts-with-nextjs-typescript-4pba`

If the user do not publish to an organization account, or we only want to retrieve articles published to an organization account using slug would be enough, as {username} can just be defaulted to the user or organisation name.

Clicking on the title in the card will navigate to post/{user}/{slug} using next.js [dynamic routes](https://nextjs.org/docs/routing/dynamic-routes)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pur40esylqkv26z58c2k.png)

```
<Link href={`posts${post.path}`}>{post.title}</Link>

```

Since this is a dynamic route, we will also need [getStaticPaths()](https://nextjs.org/docs/basic-features/data-fetching/get-static-paths)

```
//pages/posts/[user]/[slug].js
export async function getStaticPaths() {
    const res = await fetch(`https://dev.to/api/articles?username=cherylli`);
    const posts = await res.json()

    return {
        paths: posts.map(post => ({
            params: {
                user: post.path.split('/')[0],
                slug: post.slug
            }
        })),
        fallback: 'blocking',
    };
}

```

it fetches all my articles and returns user, and slug params, since I blog on both my personal and an organization account, the user param will vary based on where I published the article.

We can use these params in getStaticProps() to retrieve the single article,

```
//pages/posts/[user]/[slug].js
export const getStaticProps = async ({params}) => {
    const res = await fetch(`https://dev.to/api/articles/${params.user}/${params.slug}`);
    const post = await res.json()

    return {
        props: {
            post
        },
        revalidate: 30
    };
};

```

Now post can be passed into the page component, and `post.body_html` is the body of the post in html.

```
//pages/posts/[user]/[slug].js
const BlogPage = ({post}) => {
    return (
        <div className={styles.container}>
            // add content using the post props, and style the page
            <div dangerouslySetInnerHTML={{ __html: post.body_html }} />

        </div>
    );
};

```

![Single Page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mop50ktmchxuwuz3fzbw.png)

# Notes

#### Using ID instead of Slug

We can also use the article id instead of slug, the endpoint would be `https://dev.to/api/articles/{articleId}`. This simplifies the code since we do not have to worry about whether the article is published to a personal account or an organization account. The single article page url would be /posts/{id} instead.

#### Using [Incremental Static Generation (ISR)] (https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration)

Since SSG generates the pages on build time, newly published articles won't be added to the index page without a re-build. ISR can be used to create/update static pages after the site is built.