Create a component & fetch GitHub user details with Vue.js & Semantic UI 👩‍💻
Tags: vue, javascript, html, tutorial
Published: 2020-07-30 12:48:39

In this tutorial, you'll learn how to make a Vue component using the bare minimum requirements. What we are building is a GitHub user card which has the following content:

- The profile picture.
- GitHub profile name.
- Joining date.
- User bio.
- The number of followers.

All in all, it will look something like this:

![Semantic UI Card](https://dev-to-uploads.s3.amazonaws.com/i/kd0pfhpg1h5i7xxuyclx.jpg)

If you're familiar with [Semantic UI](https://semantic-ui.com), this is exactly what it's [card component](https://semantic-ui.com/views/card.html) is like.  

You'll get to know how to fetch data from the GitHub API endpoint and how to connect it with the [Vue instance](https://vuejs.org/v2/guide/instance.html).

Let's jump straight in!

![Jump GIF](https://media.giphy.com/media/GbIHIHhkgfpAs/giphy.gif)
<figcaption>Is this a jump or a facepalm?</figcaption>

---

## Prerequisites 🙃

Attention to extreme new-comers in web development! This tutorial is for those who have worked on:

- [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML)
- [CSS](https://developer.mozilla.org/en-US/docs/Glossary/CSS)
- [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
- [Vue.js](https://vuejs.org/) - basic component creation, knowledge on instances, props etc.

---

## Write the HTML markup 😌

Inside the `index.html` file, you need to have the root `app` element `div` which will help Vue to mount it on the webpage.

Before we move any further, add the following Semantic UI CSS CDN:

> `https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css` 

Next, we copy the card component markup code listed [here](https://semantic-ui.com/views/card.html#card).

```html
<div id="app">
    <!-- Template from Semntic UI docs -->
    <div class="ui card">
      <div class="image">
        <img src="https://semantic-ui.com/images/avatar2/large/kristy.png">
      </div>
      <div class="content">
        <a class="header">Kristy</a>
        <div class="meta">
          <span class="date">Joined in 2013</span>
        </div>
        <div class="description">
          Kristy is an art director living in New York.
        </div>
      </div>
      <div class="extra content">
        <a>
          <i class="user icon"></i>
          22 Friends
        </a>
      </div>
    </div>
  </div>
```
As you can see, under the `ui card` class, we have an [`image`](https://semantic-ui.com/elements/image.html) which holds the default avatar. After this, we have a [`content` block](https://semantic-ui.com/views/card.html#content-block) that holds all the details like the [`header`](https://semantic-ui.com/elements/header.html), [metadata](https://semantic-ui.com/views/card.html#metadata), the [`description`](https://semantic-ui.com/views/card.html#description) and finally the [`extra content`](https://semantic-ui.com/views/card.html#extra-content) which contains number of friends.      

## Write the Vue! 😎

Just before the closing `</body>` tag, add the Vue.js CDN script:

> `<script src="https://unpkg.com/vue"></script>`

Make a new _main.js_ file under the same project folder, [link it with your HTML](https://www.w3schools.com/tags/att_script_src.asp), and then create the [Vue instance](https://vuejs.org/v2/guide/instance.html).


### Code the component

Create the new component template at the top of the `body`. This is where the card will render:

`<github-card username="username"></github-user-card>`

The next step is to register our component. We use [`Vue.component`](https://vuejs.org/v2/api/#Vue-component) method. Let's give it a name `github-card`. We need a single prop, `username` which is of `type: String` and is made `required` by default as we need it to hit the GitHub API endpoint.

Our user details will be stored in the [`data()`](https://vuejs.org/v2/api/#data) property. Next, we need to have a method to call the GitHub API, so we will use the much popular [Axios library](https://github.com/axios/axios) to fetch the details. Make sure you grab its CDN by including the following script:

> `https://unpkg.com/axios/dist/axios.min.js`

Now, this [AJAX](https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX/Getting_Started) call will be done in two places:

- First, once the component is created.
- Second, before it's mounted to the document. 

Checkout [this lifecycle diagram](https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram) for better context.   

So, inside the [`created`](https://vuejs.org/v2/api/#created) hook, we use the [`get()`](https://github.com/axios/axios#axiosgeturl-config) method to pass the API URL. i.e. `https://api.github.com/users/${this.username}`. The [response](https://github.com/axios/axios#note-commonjs-usage) data is set to the `user` property.

Here's the code:

```js
Vue.component('github-card', {
      props: {
        username: {
          type: String,
          required: true
        }
      },
      data() {
        return {
          user: {}
        };
      },
      async created() {
        const response = await axios.get(`https://api.github.com/users/${this.username}`);
        this.user = response.data;
      }
    });

    new Vue({
      el: '#app',
    });
```
### Create the template

We use the [X-Template](https://vuejs.org/v2/guide/components-edge-cases.html#X-Templates) method to put the above HTML syntax. But first, we give it a suitable `id` of `github-card-template` making sure we also update the Vue code by adding the `template` with this `id`. Cut all the Semantic UI HTML and add it under the new X-Template script.

The GitHub API format and all the data which we can get is [available on their website](https://api.github.com/) in the JSON format.

Let's replace the hardcoded values with the newly accessible `user` object from the API. Here are the replacements:

- `<img src="https://semantic-ui.com/images/avatar2/large/kristy.png">` -> `<img :src="user.avatar_url">`
- "Kristy" -> `{{ user.name }}`
- "Joined in 2013" -> `Joined in {{ user.created_at }}`
- "Kristy is an art director living in New York." -> `{{ user.bio }}`
- "22 Friends" -> `{{ user.followers }} Followers`   

Remember that we're using the [moustache format](https://vuejs.org/v2/guide/syntax.html#Text) for the JavaScript code.

Here's the new code:

```js
<script type="text/x-template" id="github-card-template">
    <div class="ui card">
      <div class="image">
        <img :src="user.avatar_url">
      </div>
      <div class="content">
        <a :href="`https://github.com/${username}`" class="header">{{user.name}}</a>
        <div class="meta">
          <span class="date">Joined in {{user.created_at}}</span>
        </div>
        <div class="description">
          {{user.bio}}
        </div>
      </div>
      <div class="extra content">
        <a :href="`https://github.com/${username}?tab=followers`">
          <i class="user icon"></i>
          {{user.followers}} Followers
        </a>
      </div>
    </div>
  </script>
```
As you can see, I've added links in between the name and the follower count using the [`:href`](https://vuejs.org/v2/guide/syntax.html#Arguments) argument.

Refresh the browser page and there you have it! You've just created a GitHub component in Vue and styled it with Storybook. How cool!

Here's what [@nickytonline](https://dev.to/nickytonline)'s GitHub card looks like: 😉

![Nick Taylor's Github card](https://dev-to-uploads.s3.amazonaws.com/i/vk6fwrcx9rno8ax1rxrb.jpg)

---

## Where to next? 🤔

- Make these cards for multiple users! 
- Use GitHub data to get more info
- Use Semantic UI's other components to display the data.

---

_Thanks for reading, I appreciate it! Have a good day. (✿◕‿◕✿)_

---

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="en" dir="ltr">Who here can relate? 😓<br><br>Documentation is rarely closed as duplicate, just saying... 😉<br><br>Find Microsoft Docs this way: <a href="https://t.co/eq5hQaVjPn">https://t.co/eq5hQaVjPn</a><br><br>Image source: <a href="https://t.co/gnY04c5qul">https://t.co/gnY04c5qul</a><a href="https://twitter.com/hashtag/DevHumour?src=hash&amp;ref_src=twsrc%5Etfw">#DevHumour</a> <a href="https://twitter.com/hashtag/Programming?src=hash&amp;ref_src=twsrc%5Etfw">#Programming</a> <a href="https://twitter.com/hashtag/Developer?src=hash&amp;ref_src=twsrc%5Etfw">#Developer</a> <a href="https://twitter.com/hashtag/ICYMI?src=hash&amp;ref_src=twsrc%5Etfw">#ICYMI</a> <a href="https://t.co/KIrCbhE7Q5">pic.twitter.com/KIrCbhE7Q5</a></p>&mdash; Microsoft Developer UK (@msdevUK) <a href="https://twitter.com/msdevUK/status/1287412113519128577?ref_src=twsrc%5Etfw">July 26, 2020</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

---

#### [📫 Subscribe to my weekly developer newsletter 📫](https://mailchi.mp/f59beeac6b9b/devupdates)

<hr/>

_[Daily](https://r.daily.dev/get?r=devto) delivers the best programming news every new tab. We will rank hundreds of qualified sources for you so that you can hack the future._

[![Daily Poster](https://dev-to-uploads.s3.amazonaws.com/i/b996k4sm4efhietrzups.png)](https://r.daily.dev/get?r=devto)