DEV Community

Cover image for Embed Your Latest DEV Posts Anywhere πŸ’Œ
Andrew Healey
Andrew Healey

Posted on • Updated on • Originally published at healeycodes.com

Embed Your Latest DEV Posts Anywhere πŸ’Œ

Let's look at how the DEV.to API can be used to embed a list of your recent posts. We'll also sort them by their positive reactions! All it takes is a splash of client-side JavaScript. The API is not released yet, is not documented, and will likely change but I'll keep this post up to date.

Here's an test page which uses the tiny library we'll be writing. We'll be creating a plain list to keep things extendable. You can also skip straight to the repository to check out the final code.

How easy is the DEV API to use?

Easy. The articles route is https://dev.to/api/articles?username=$user. Originally, I experimented with getting more than the latest 30 posts, which is the default. This can be done by adding &page=$pageNum β€” but requesting multiple pages introduces a delay. Since it's impossible to know the number of pages of posts, you need to keep going until you hit an empty page. A late-loading list doesn't make for great UX.

Let's start by using the Fetch API to make a request from the user's browser.

fetch(`https://dev.to/api/articles?username=healeycodes`)
    .then(function (response) {

        // Parse it as JSON
        return response.json();
    }).then(function (posts) {

        // An array of posts
        console.log(posts);
    })

Looking good. Let's neaten this up with some JSDoc comments so the code is more accessible. We'll also wrap it in a function.

/**
 * Get a DEV user's post objects.
 * Only fetches previously 30 posts. Using `&page=X` is too slow.
 * @param {string} username - DEV username, e.g. 'ben'.
 * @returns {array} User's post objects.
 */
function getPosts(username) {

    // Assume that `api` is defined as a constant
    return fetch(`${api}/articles?username=${username}`)
        .then(function (response) {
            return response.json();
        })
        .then(function (posts) {

            // Sort the array in place with a compare function
            return posts.sort((a, b) => b.positive_reactions_count - a.positive_reactions_count);
        });
}

A list of 30 posts is maybe a bit much. We'll cut it down later. For now, notice how we sorted the array in place with a compareFunction. We used a shorthand version. Compare functions are typically written by returning -1, 1, or 0 when comparing the two parameters. However, all that matters is that the compare function is consistent.

We want to create a simple list that can be styled with CSS. Sensible class names might be dev-feed-list and dev-feed-item. We'll need an element to attach this list to as well so that should be an argument that our library takes. With JavaScript, we can add classes, and create lists and attach them on the fly like this:

// An unordered list
const list = document.createElement('ul');

// A list item
const item = document.createElement('li');
item.classList.add('dev-feed-item');
item.innerText = 'I am a list item.';

// Let's create a relation between them
list.appendChild(item);

// Now between the list and the document, rendering the list
// body -> ul -> li
document.body.appendChild(list);

Let's create a function that builds the elements that will make up our embedded list. We'll use the getPosts function from earlier to get our sorted array of posts.

/** 
 * Creates a DEV feed of posts.
 * @constructor
 * @param {Element} elem - Place list of posts inside this element.
 * @param {string} username - DEV username, e.g. 'ben'.
 * @param {number} numberOfPosts - Number of posts to list. 
 */
function createFeed(elem, username, numberOfPosts = 5) {
    const feed = document.createElement('ul');
    feed.classList.add('dev-feed-list');
    getPosts(username)

        // With our posts array
        .then(function (posts) {
            posts.length = numberOfPosts;
            posts.forEach(function (post) {

                // We create an element for each item
                const item = document.createElement('li');
                item.classList.add('dev-feed-item');

                // As well as a link for users to click through
                const link = document.createElement('a');
                link.href = post.url;
                link.innerText = post.title;

                // ul -> li -> a
                item.appendChild(link);
                feed.appendChild(item);
            });

            // Attach the list of posts, rendering it
            elem.appendChild(feed);
        });
}

If we bundle this all together as a script, we can generate lists by calling createFeed(element, username, numberOfPosts) where element is the container for the list and username is a valid DEV user, and numberOfPosts is the number of posts we want to render.

By allowing a custom number of posts to be fetched, as well as using sensible CSS classes, our library is extensible and can be used as a tiny module!


Join 150+ people signed up to my newsletter on programming and personal growth!

I tweet about tech @healeycodes.

Top comments (9)

Collapse
 
ben profile image
Ben Halpern

Cool!! We'll try to keep the API compatible once it gets released πŸ™‚

Collapse
 
oohsinan profile image
Omar Sinan

Thank you for this! Used it for my blog :)

Collapse
 
healeycodes profile image
Andrew Healey

Neat! Your site looks great on mobile πŸ‘

Collapse
 
oohsinan profile image
Omar Sinan

Thanks, appreciate it! :D

Collapse
 
katiekodes profile image
Katie

I kept hearing about "the API" and wondered what everyone was talking about. This answers that question; thanks!

Collapse
 
snowleo208 profile image
Yuki Cheung

Really nice! I know this API for the first time, it is more convenient than fetching RSS feed and only can get title and link :)

Collapse
 
thomasbnt profile image
Thomas Bnt β˜•

Ohh nice!

https://tenor.com/K0T5.gif

Collapse
 
chrisrhymes profile image
C.S. Rhymes

Nice. It would be good to ask for posts pre sorted from the api, so for example you can get the 5 posts with the most positive reactions, rather than requesting 30 and filtering them out.

Collapse
 
healeycodes profile image
Andrew Healey

Yes! I agree. I'm looking forward to seeing how the API develops.