How to embed posts from dev.to in your website page
Published: 2023-01-22 12:10:35

I created a small js hack, that can help you embed posts from dev.to and present it in your website, using the dev.to API.

there are few easy steps to implement this script:

1. creating an object array of the posts you like to embed

2. creating an html template of an embeded post
3. creating an html placeholder element, to append posts to
4. looping through the posts array, and foreach 
- fatch the data from the api, 
- arrange it's data in a clone of the template you created, 
- appending it to the placeholder
5. add some css

### 1 - OK, let's begin by creating the array:

```javascript
  var news_posts = [
    {
          "slag": "open-source-developement-cource-57no",
          "user": "kobkob2018"
      }
    
      ,{
          "slag": "why-use-a-version-control-system-3o93",
          "user": "szabgab"
      }
    
      ,{
          "slag": "osdc-course-with-gabor-4hfi",
          "user": "shulyavraham"
      }  
  ];
```
### 2 - Now let's create the article templae:
good practice to put it at the bottom of your html. 
notice it is inside a hidden div with display:none styling, so you can reuse this div to build other templates as well..

The actuall element we are going to use for the template is the one with the classname "news-post-template"

```javascript
<div id="apitoui_template" class = "apitoui-template" style="display:none">
  <div class = "news-post-template" >
    <a href = "#" target = "_NEW" class = "news-post-link-to" >
      <div class = "news-post-wrap" >
            <div class="post-left-side">
              <img class = "img-placeholder" src = "" alt = "" />
            </div>
            <div class="post-right-side">
              <h4>
                <span class = "title-plaeceholder" ></span>
              </h4>
              <div class="small-details">
                <small class="news-post-details">
                  <span class = "username-plaeceholder" ></span> ・ <span class = "date-plaeceholder" ></span> ・ <span class = "read-plaeceholder" ></span> minutes read
                </small>
              </div>
              <div class="post-description">
                <span class="description-plaeceholder"></span>
              </div>
              <div class="taglist">
                <small class="news-post-taglist">
                    <span class = "taglist-plaeceholder" ></span>
                </small>
              </div>
            </div>
      </div>
    </a>
  </div>
</div>
```

Can you see that there is allot of HTML here, but really no content? 
notice that there are allot of elements with an xxx-placeholder classes. 
later in the script, we will grab the values we fatched from the API and put them there.

### 3 - the placeholder for where the posts will be:
you just put this on the page, where you want the articles to appear:
```javascript
<div id="articles_placeholder" class = "dev-to-articles">


</div>
```
it is an empty element that will be filled with the fatched posts

### 4 - the script goes here! Fatching the posts from dev.to and put them in place:
```javascript
  news_posts.forEach(newpost => {
    if(newpost.slag == 'none'){
      return;
    }
    fetch('https://dev.to/api/articles/'+newpost.user+'/'+newpost.slag).then((res) => res.json()).then(article => {
      //console.log(article);
      let articles_placeholder = document.getElementById("articles_placeholder");

      let article_template = document.getElementById("apitoui_template")
            .querySelector(".news-post-template")
            .cloneNode(true);

      article_template.querySelector(".title-plaeceholder").innerHTML = article.title;
      let ar_image = article_template.querySelector(".img-placeholder");
      ar_image.src = article.user.profile_image_90;
      ar_image.title = article.user.name;
      articles_placeholder.append(article_template);
      article_template.querySelector(".username-plaeceholder").innerHTML = article.user.name;
      article_template.querySelector(".date-plaeceholder").innerHTML = article.readable_publish_date;
      article_template.querySelector(".read-plaeceholder").innerHTML = article.reading_time_minutes;
      console.log(article.description);
      article_template.querySelector(".description-plaeceholder").innerHTML = article.description;
      let taglist_placeholder = article_template.querySelector(".taglist-plaeceholder");
      article.tags.forEach(tag => {
        taglist_placeholder.append("#"+tag+" ");
      });
      article_template.querySelectorAll(".news-post-link-to").forEach(link => {
        link.href = article.canonical_url;
      });
    });
  });
```

#### So what do we actually see here?
first thing is, that we loop through the object array we created earlier: 
```javascript
  news_posts.forEach(newpost => {
    if(newpost.slag == 'none'){
      return;
    }
    ... //code goes here
  });
```

now, for each object, we grab the username and the slag info, and use it to fetch the article from the api:

```javascript
        fetch('https://dev.to/api/articles/'+newpost.user+'/'+newpost.slag)
      .then((res) => res.json())
      .then(article => {
        console.log(article);
        ... //code goes here
    });

```

after fetching the article data you can console.log it, to see which info you recived and what you can use to fill your template clone

#### So now, let's create the template clone: 
```javascript
      let article_template = document.getElementById("apitoui_template")
            .querySelector(".news-post-template")
            .cloneNode(true);

```

#### now we can append data from the article info into the clone's html elements.
```javascript
article_template.querySelector(".title-plaeceholder").innerHTML = article.title;
```


```javascript
      let ar_image = article_template.querySelector(".img-placeholder");
      ar_image.src = article.user.profile_image_90;
      ar_image.title = article.user.name;
```

```javascript
      article_template.querySelector(".username-plaeceholder").innerHTML = article.user.name;
      article_template.querySelector(".date-plaeceholder").innerHTML = article.readable_publish_date;
      article_template.querySelector(".read-plaeceholder").innerHTML = article.reading_time_minutes;
      article_template.querySelector(".description-plaeceholder").innerHTML = article.description;
```

```javascript
      let taglist_placeholder = article_template.querySelector(".taglist-plaeceholder");
      article.tags.forEach(tag => {
        taglist_placeholder.append("#"+tag+" ");
      });
```
### Don't forget to assign the href attribute to the article's link (or links):
```javascript
      article_template.querySelectorAll(".news-post-link-to").forEach(link => {
        link.href = article.canonical_url;
      });
```
### And now, append it to the page:
```javascript
      let articles_placeholder = document.getElementById("articles_placeholder");
      articles_placeholder.append(article_template);
```

### 5 - Last, but not least, add some CSS to look almost like an embed in dev.to:

(using some sass here...)
```javascript
.news-post-template a.news-post-link-to:hover{
    text-decoration: none;
}

.news-post-wrap{
    display: flex;
    background: white;
    border: 1px solid gray;
    margin: 25px;
    padding: 10px;
    border-radius: 5px;
    box-shadow: 3px 3px 3px grey;
    color: black;
    max-width: 700px;
    
    .post-left-side{
        margin: 10px;
        margin-right: 20px;
        width: 70px;
        img{
            border-radius: 50%;
            width: 65px;
        }
    }
    h4{
        font-weight: normal;
        font-size: 24px;
        line-height: 18px;
        padding-top: 12px;
    }
    .post-description{
        font-size: 14px;
        line-height: 14px;
        padding: 0px 14px;
    }
    .small-details{
        font-weight: bold;
    }
}
```


Basically, Thats it.
There are also some other ways to fatch articles. you can get all user articles as an array, etc..

You can see a good example in this article:
{% embed https://dev.to/olawanle_joel/fetch-your-posts-from-dev-to-api-with-javascript-i36 %}