DEV Community

Cover image for Bringing DEV.TO to Your Blog
Charles D. Villard
Charles D. Villard

Posted on

Bringing DEV.TO to Your Blog

If you follow software or web developers on Twitter, you're likely to have spotted some grumblings surrounding the blogging platform Medium. Many developers are considering making the move away from Medium ever since they took a walled-garden approach and started asking readers to pay a monthly fee for content written for free. Two popular options have been discussed frequently: either roll out a personal, custom blog or move content to another popular platform, dev.to (from which you're reading this article, by the way.)

Both are viable options, and given the prevalence of static site generators, are easy to accomplish. While building a blog grants you more control over its presentations, the benefits of regularly posting a blog on dev.to are nothing to sneeze at. The immediate upside is access to a large community of supportive and like-minded individuals, as well as built-in moderated commenting, SEO, and a conveniently located reader base at which to target your niche programming content. The dev.to team are also very transparent about what they're working on and what they can share, so you'll always see where things are going down the road.

Now, I will admit that I myself am a bit biased about dev.to. I've followed its progress from Ben Halpern's fledgling personal blog idea of The Practical Dev all the way to the robust platform and business it is today. If I could, I'd invest in it, is how much I adore this platform. All of that is to say, take my recommendation with a grain of salt. I feel like it's a great place to build your content and share it with the community, but I can see where having your own blog on your own site might also have benefits. Hopefully this post will show you a way that you can have both.

From the OG mailer packs.

A much requested but apparently little known feature of dev.to is its new Articles API, released earlier this May. It's a straight-forward REST API that allows authenticated users to create, update, and read posts. In updating my own personal blog, I've been experimenting with using it to bring posts in and display them on dedicated pages, and I feel that it has a lot to offer. I haven't delved into all the endpoints available to date, but I'll try and touch on what I have so far and discuss my plans for what I haven't.

What I present here is more of an experimental strategy than a prescriptive path towards using the DEV Articles API with static site generators. While the code will be from my own current implementations, I recommend looking at it as just a suggestion.

A quick note about assumptions and tech before moving forward.

As I mentioned before, a lot of the discussion I've seen has mentioned the option of rolling out a blog using a static site generator. Thus, the rest of this article assumes some familiarity with at least one static site generator tool. If you're unfamiliar with what a static site generator is, I highly recommended learning about the JAMStack architecture, and maybe exploring Gatsby or Gridsome, before coming back to this. Static site generators are a massive topic, but I've found these easy to get started with. I've already implemented this using Gridsome, a static site generator built using Vue.js, so my examples will be modeled on that. To the best of my knowledge, most static site generators will have the infrastructure in place to accomplish this, so don't feel locked into any one particular tool.

Displaying a List of DEV Posts

Let's start with getting a list of posts. The DEV Articles API offers a GET endpoint for retrieving posts that doesn't require any access tokens. All it takes is a query string appended to https://dev.to/api/articles.

https://dev.to/api/articles # Gets the top 30 "hottest" articles
https://dev.to/api/articles?tag=keyword# Gets articles tagged with "keyword"
https://dev.to/api/articles?username=thatUser # Gets articles written by thatUser
https://dev.to/api/articles?state=fresh # Gets "fresh" articles
https://dev.to/api/articles?state=rising # Gets "rising" articles
https://dev.to/api/articles?top=10 # Gets the top positively-reacted-to
                                   # articles from the past 10 days
Enter fullscreen mode Exit fullscreen mode

Each request usually paginates the returned posts to 30 articles each. Getting the next thirty requires adding a page query string, so finding the 31st to 60th top articles from the past 10 days would look like:

https://dev.to/api/articles?top=10&page=2
Enter fullscreen mode Exit fullscreen mode

Each of the JSON objects in the array you get back will contain metadata and front matter for each post that fit the query string parameters. So if we were to use https://dev.to/api/articles?username=cdvillard in the browser, we would get back an array of these suckers:

{
  type_of: "article",
  id: 90594,
  title: "RTFC: Why patience is a developer's best friend",
  description: "Patience as a virtue can mean a lot to a developer.",
  cover_image: "https://res.cloudinary.com/practicaldev/image/fetch/s--Rqg-VarX--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://thepracticaldev.s3.amazonaws.com/i/36d4a4hhje64epv8248d.jpg",
  published_at: "2019-03-12T22:24:53.528Z",
  tag_list: [
    "edit",
    "beginners",
    "productivity",
    "cdvillard"
  ],
  slug: "rtfc-why-patience-is-a-developers-best-friend-l95",
  path: "/cdvillard/rtfc-why-patience-is-a-developers-best-friend-l95",
  url: "https://dev.to/cdvillard/rtfc-why-patience-is-a-developers-best-friend-l95",
  canonical_url: "https://dev.to/cdvillard/rtfc-why-patience-is-a-developers-best-friend-l95",
  comments_count: 0,
  positive_reactions_count: 11,
  published_timestamp: "2019-03-12T22:24:53Z",
  user: {
    name: "Charles D. Villard",
    username: "cdvillard",
    twitter_username: "cdvillard",
    github_username: "cdvillard",
    website_url: "http://cdvillard.github.io",
    profile_image: "https://res.cloudinary.com/practicaldev/image/fetch/s--cX9wiyae--/c_fill,f_auto,fl_progressive,h_640,q_auto,w_640/https://thepracticaldev.s3.amazonaws.com/uploads/user/profile_image/11581/9217c42f-218d-4a3c-b565-9a7e9b597cd1.jpg",
    profile_image_90: "https://res.cloudinary.com/practicaldev/image/fetch/s--xG2hWmsO--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://thepracticaldev.s3.amazonaws.com/uploads/user/profile_image/11581/9217c42f-218d-4a3c-b565-9a7e9b597cd1.jpg"
  }
}
Enter fullscreen mode Exit fullscreen mode

If you've published anything on DEV before, I encourage you to give it a shot and see what yours look like.

Following the recommended practices of your static site generator of choice, create a GET request for the articles you wish to query. This can be done using XMLHttpRequest, but I used the Axios library to make it a bit easier on myself.

  // Starts a GET request to the DEV API
  axios.get("https://dev.to/api/articles?username=cdvillard&tag=cdvillard")
      .then(response => { // When a response is received
        this.blogList = [...response.data]; // Add that to my Vue data
      })
      .catch(err => { // If something goes wrong
        console.log(err); // Log it to the console
      })
  }
Enter fullscreen mode Exit fullscreen mode

You may have noticed that I'm querying not only my username in the request but also a tag of . . . my username? Why? Well, the DEV API returns anything it considers an article. This includes any posts tagged "discuss" which is DEV's way of indicating forum-like posts. Tagging articles I'd like to display with my username is simply a workaround to filter those out.

Bringing that data to the front end depends on the architecture of your particular static site generator, but once you've learned how to access it, you can iterate over it. Much of the power of a static site generator, after all is in being able to quickly build and implement a website, which usually means additional functionality for creating iterative markup using loops. In Gridsome, that means using Vue's v-for directive to call on the data and build on each object.

<!-- The v-for creates an instance of each "blog-preview" component 
for each "blog" in the "blogList" we got earlier, 
and attaches each property from the "blog" to an associated property 
of the "blog-preview" component. Kind of like connect-the-dots. 
If you want to learn more about Vue components and props, start with 
the Vue documentation at https://vuejs.org/v2/guide/components.html -->
<blog-preview v-for="blog of blogList"
  :key="blog.id"
  :blog-title="blog.title"
  :blog-description="blog.description"
  :blog-link="blog.canonical_url"
></blog-preview>
Enter fullscreen mode Exit fullscreen mode

If all works out, you should see your articles being listed on your page of choice. If you want to see exactly how I accomplished this, feel free to take a look at my repo here.

The homepage of charlesvillard.co with blog articles from dev.to by "cdvillard" listed

My current work-in-progress placeholder with my posts

Displaying a DEV Post

So we've gotten a list of posts and links, but we haven't actually displayed a proper post. To do that, we need to make a call to a different API endpoint, specifically to the id of the article we're looking for. There isn't as much surface to work with on this part of the API, but you do get all of the information regarding your article, including the HTML generated by DEV's markdown renderer. Making a request to https://dev.to/api/articles/90594 will return a JSON object like this:

{
  type_of: "article",
  id: 90594,
  title: "RTFC: Why patience is a developer's best friend",
  description: "Patience as a virtue can mean a lot to a developer.",
  cover_image: "https://res.cloudinary.com/practicaldev/image/fetch/s--Rqg-VarX--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://thepracticaldev.s3.amazonaws.com/i/36d4a4hhje64epv8248d.jpg",
  readable_publish_date: "Mar 12",
  social_image: "https://res.cloudinary.com/practicaldev/image/fetch/s--ENrc8Sz1--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://thepracticaldev.s3.amazonaws.com/i/36d4a4hhje64epv8248d.jpg",
  tag_list: "edit, beginners, productivity, cdvillard",
  tags: [
    "edit",
    "beginners",
    "productivity",
    "cdvillard"
  ],
  slug: "rtfc-why-patience-is-a-developers-best-friend-l95",
  path: "/cdvillard/rtfc-why-patience-is-a-developers-best-friend-l95",
  url: "https://dev.to/cdvillard/rtfc-why-patience-is-a-developers-best-friend-l95",
  canonical_url: "https://dev.to/cdvillard/rtfc-why-patience-is-a-developers-best-friend-l95",
  comments_count: 0,
  positive_reactions_count: 11,
  created_at: "2019-03-12T22:22:46Z",
  edited_at: "2019-05-18T13:24:39Z",
  crossposted_at: null,
  published_at: "2019-03-12T22:24:53Z",
  last_comment_at: "2019-03-12T22:24:53Z",
  body_html: "<p>I'm typically not a patient person. It's a flaw I cop to a lot, and it's something I actively...",
  ltag_style: [ ],
  ltag_script: [ ],
  user: {
    name: "Charles D. Villard",
    username: "cdvillard",
    twitter_username: "cdvillard",
    github_username: "cdvillard",
    website_url: "http://cdvillard.github.io",
    profile_image: "https://res.cloudinary.com/practicaldev/image/fetch/s--cX9wiyae--/c_fill,f_auto,fl_progressive,h_640,q_auto,w_640/https://thepracticaldev.s3.amazonaws.com/uploads/user/profile_image/11581/9217c42f-218d-4a3c-b565-9a7e9b597cd1.jpg",
    profile_image_90: "https://res.cloudinary.com/practicaldev/image/fetch/s--xG2hWmsO--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://thepracticaldev.s3.amazonaws.com/uploads/user/profile_image/11581/9217c42f-218d-4a3c-b565-9a7e9b597cd1.jpg"
  }
}
Enter fullscreen mode Exit fullscreen mode

The body_html property will likely be what catches your eye, as using that can cut out much of the cruft that comes with formatting a blog post.

Posting to, and Updating Posts on, DEV

When it comes to posting to DEV using the API, I have to admit that I'm still learning to use it myself. I have yet to experiment with it, but I feel that this is where the real power of DEV's API comes to bear. In theory, someone with a statically generated site will be able to cross-post to dev.to while maintaining their own site. How that's done exactly is a matter for another blog post, but given that we're working within the JAMStack, this is likely where serverless functions will come into play. I'll be experimenting with Netlify and a functions service in the coming days to see how to implement this.

Where to Go From Here

What I hope you'll take away from this is how flexible the DEV API can be, and how it is possible to both roll your own blog and post at DEV.to as well. As of this writing, I'm unable to comment on the effects doing so may have on SEO, but I don't foresee any significant negative impact that wouldn't drive traffic to finding you. Personally, I hope that those of you thinking about it will join the community and help make it all the more interesting. The more voices, the better.

Top comments (8)

Collapse
 
ben profile image
Ben Halpern

Really cool, will definitely circulate this!

Collapse
 
cdvillard profile image
Charles D. Villard

I'm glad you think so! Thank you!

Collapse
 
flrnd profile image
Florian Rand

You know, I've tried few times clicking in that screen capture links. I feel old.

(really cool! Can't wait to try it on my blog!)

Collapse
 
cdvillard profile image
Charles D. Villard

I'm glad you like it! If you have any questions, feel free to reach out. I'm going to try and expand on this, so keep posted.

Collapse
 
ieuantwalker profile image
Ieuan Walker

Its great that they have an API, but do you know of any Wordpress plugins that could automattically publish and update posts?

Collapse
 
cdvillard profile image
Charles D. Villard

Unfortunately,to date, I don't know of any plugins that do that specifically from DEV, but I imagine there's one that makes it possible.

Collapse
 
voidjuneau profile image
Juneau Lim

Wow, I thought there's a way but couldn't see API or RSS button so always wondering. Thanks for the post!

Collapse
 
jgibba profile image
Jon

Awesome article, looking to experiment with this someday soon. Thanks!