Jamstack application with Gatsby and Bugfender
Tags: engineering, javascript, react
Published: 2021-05-20 15:16:48

---
title: Jamstack application with Gatsby and Bugfender
published: true
date: 2021-01-20 10:51:59 UTC
tags: Engineering,JavaScript,React
canonical_url: https://bugfender.com/blog/jamstack-application-with-gatsby-and-bugfender/
---

[Jamstack](https://jamstack.org/) is a modern web development architecture based on client-side JavaScript, reusable APIs, and prebuilt Markup. It is not yet a full technology stack like MEAN, MERN or LAMP. Rather, it is an architectural concept built using JavaScript, API and Markup.

Before we look at how to use Jamstack in more detail, let’s examine its component parts and what they represent:

[![](https://bugfender.com/wp-content/uploads/2021/01/Jamven.png)](https://bugfender.com/wp-content/uploads/2021/01/Jamven.png)<figcaption>Jamstack is base on JavaScript, API and Markup</figcaption>

Jamstack applications are hosted, in their entirety, on a Content Delivery Network (**CDN)** or an Application Delivery Network **(ADN)**. Everything is stored in  **GIT,** and **automated builds**  are provided with a workflow when developers push the code. The pre-built markup is **automatically deployed** to the CDN/ADN.

These characteristics provide a bunch of significant benefits:

- The whole process is **practically serverless** , removing a lot of failure points and potential security exploits.
- The pre-built content served via CDN provides **super-fast user experiences**.
- The reduced complexity of development **lowers costs**.
- The Develop => Build => Test => Deploy Cycle is very  **well-managed**.

## How to Build Jamstack Apps

Today, there are myriad tools, frameworks, library and services available to build and manage Jamstack applications. Among the most popular are static site generators (SSGs) which facilitate the construction of pre-built markups, as well as CDNs/ADNs. These SSGs come with generous price plans to deploy and host the applications, and offer both services and APIs.

One of the most popular members of the current generation of SSGs is **[Gatsby](https://www.gatsbyjs.com/)**, a React-based framework specifically designed to create prebuilt markups. As well as offering a plethora of plug-in ecosystems, Gatsby is also hooked up to a vibrant community support network.

In this post, we’re going to show you how to build Gatsby with [Bugfender](https://bugfender.com/), our remote logging service which allows users to collect logs for everything that happens in their application. It’s easy to integrate Bugfender with web apps and there are lots of SDKs available to integrate with mobile apps, too.

Ok, enough of the pitch. Let’s get moving!

## What are we building today?

We’re going to build a basic blogging site called `The Purple Blog`. In doing so, we will see that Gatsby can build such sites in double-quick time with the help of GraphQL and markdown files. During the build process, we will integrate `Bugfender` to collect application logs, create automatic user feedback, issues and crash reports, and analyze them.

When we’re done, the Gatsby and Bugfender-powered blog site may look like this:

[![](https://bugfender.com/wp-content/uploads/2021/01/Untitled-1024x582.png)](https://bugfender.com/wp-content/uploads/2021/01/Untitled.png)

### TL;DR

If at any point of time you want to look into the source code or play around with the blog site, here are the links:

> GitHub Repository: [https://github.com/atapas/gatsby-bugfender](https://github.com/atapas/gatsby-bugfender)

and

> Demo Link: [https://gatsby-bugfender.netlify.app/](https://gatsby-bugfender.netlify.app/)

### Create the Project Structure with Gatsby

We will use a Gatsby starter to create the initial project structure. To do this, you need to install Gatsby CLI globally, and the best way to do this is by opening a command prompt and running this command:

```
npm install -g gatsby-cli
```

Now, use the following command to create a Gatsby project structure.

```
gatsby new purple-blog https://github.com/gatsbyjs/gatsby-starter-default
```

We are using the `gatsby-starter-default` starter project template to create our blogging tool, as this will initiate the project with all required libraries and dependencies.

Once done, you will see a project folder called purple-blog has been created. Go to that folder and open a command prompt there. Type the following command to run the app in the development mode:

```
gatsby develop
```

Now, you should be able to access the interface using [http://localhost:8000/](http://localhost:8000/).

[![](https://bugfender.com/wp-content/uploads/2021/01/Gatsby_Default_Starter-1024x548.png)](https://bugfender.com/wp-content/uploads/2021/01/Gatsby_Default_Starter.png)<figcaption>First screen – Gatsby Default</figcaption>

### Set Up Bugfender

To kick things off, simply [create an account](https://dashboard.bugfender.com/signup) with Bugfender. Once logged in, create a Bugfender application for web apps using the Web SDK option. You can follow this [step-by-step guide](https://support.bugfender.com/en/articles/118162-first-steps-with-bugfender) to create a Bugfender application, and you will find an API key ready for you. Keep it safe.

Once you have created your app, the Bugfender dashboard will enable you to keep track of logs, issues, feedback and crashes. This is how my dashboard looks:

[![](https://bugfender.com/wp-content/uploads/2021/01/Untitled-1-1024x349.png)](https://bugfender.com/wp-content/uploads/2021/01/Untitled-1.png)<figcaption>BugFender Dashboard with an App</figcaption>

### Gatsby and Bugfender

A `gatsby`-based application can run in two different environments.

- `gatsby develop`: A development environment with hot reloading enabled. In this environment, all browser-specific APIs like `localstorage`, and objects like `window` work well.
- `gatsby build` with `gatsby serve`: This is the environment to build the app to produce deployable artifacts; once you have created them, you can run the app from the built artifacts. In this environment, the browser-specific APIs and objects will not work as the environment is based on `nodejs`. For example, the `window` object is not available in the `nodejs` and we may end up getting an error like:

[![](https://bugfender.com/wp-content/uploads/2021/01/Untitled-2.png)](https://bugfender.com/wp-content/uploads/2021/01/Untitled-2.png)<figcaption>Possible error while building a Gatsby app</figcaption>

On the other hand, Bugfender is a client-specific tool and it depends on browser-specific objects like window. Hence there is a chance that a Bugfender API that works well in the gatsby develop environment may fail in the gatsby build. We need to provide some configurations along with code changes to allow the Bugfender APIs to work with both the Gatsby environments.

### Install Bugfender SDK

Open a command prompt and the root of the project folder and use this command to install the Bugfender SDK:

```
yarn add @bugfender/sdk # Or, npm i @bugfender/sdk
```

### Configure gatsby-node for Bugfender

Open the file named gatsby-node.js and add the following content:

```
exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
   if (stage === "build-html") {
     /*
       * During the build step, @bugfender will break because it relies on
       * browser-specific APIs. Fortunately, we don’t need it during the build.
       * Using Webpack’s null loader, we’re able to effectively ignore @bugfender
       * during the build. (See src/utils/bugfender.js to see how we prevent this
       * from breaking the app.)
       */
     actions.setWebpackConfig({
       module: {
         rules: [
           {
             test: /@bugfender/,
             use: loaders.null(),
           },
         ],
       },
     })
   }
 }
```

A few things are going on here. We are telling gatsby that Bugfender is a client-specific thing and it is not required at the build stage. Using Webpack’s null loader, we’re able to effectively ignore Bugfender during the build. The loader checks for an npm package that starts with the name @bugfender, then ignores it. Simple!

### Create a Utility for Bugfender APIs

Next, we will create a utility file to wrap the Bugfender APIs so that they can be ignored at the build stage. You can do this by creating a folder called `utils` under `src,` then creating a file called `bugfender.js` under `src\\utils` with the following content:

```
import { Bugfender } from '@bugfender/sdk'
const isBrowser = typeof window !== "undefined"

const GatsbyBugfender = {
    init: () => {
        if (!isBrowser) {
            return
        }
        Bugfender.init({
            appKey: '',
        })
    },

    log: (...messages) => {
        if (!isBrowser) {
            return
        }
        Bugfender.log(messages.join( ))
    },

    error: (...messages) => {
        if (!isBrowser) {
            return
        }
        Bugfender.error(messages.join( ))
    },

    sendUserFeedback: (key, value) => {
        if (!isBrowser) {
            return
        }
        Bugfender.sendUserFeedback(key, value)
    },

    sendIssue: (key, value) => {
        if (!isBrowser) {
            return
        }
        Bugfender.sendIssue(key, value)
    },

    sendCrash: (key, value) => {
        if (!isBrowser) {
            return
        }
        Bugfender.sendCrash(key, value)
    }

}

export default GatsbyBugfender;

```

We are actually taking care of a few things here:

- First, we’re checking that the app is running in the browser mode or nodejs mode.
- We’re allowing the calling of a Bugfender API if we’re sure it is running in the browser mode.
- The `init` function uses the `API_KEY` you noted down while setting up `Bugfender` a while ago.
- You can add [all the Bugfender APIs](https://js.bugfender.com/#usage) or just the ones you need.

### Use the API function from the Utility

Now we will be able to initialize and use Bugfender in the Gatsby code without any issues.

Let’s start by taking a look at a single usage. Open the file, `src/pages/index.js` and import the `GatsbyBugfender` utility we have created:

```
import GatsbyBugfender from '../utils/bugfender' 
```

Call the `init` method after all the imports:

```
// all imports
....
GatsbyBugfender.init();

const IndexPage = ({data}) => (
....
```

Now you can call the Bugfender APIs in the Gatsby app from any of the pages, components or templates. Here is an example:

```
if (posts.length > 0) {
    GatsbyBugfender.log(`${posts.length} posts found in the repository`)
    GatsbyBugfender.sendUserFeedback('Posts created', 'Default Posts created Successfully!')
  } else {
    GatsbyBugfender.sendIssue('No Posts Found')
  }
```

### The Blogging App

Now we will focus on building `The Purple Blog`.

To do so, we can take advantage of _Gatsbyjs’s_ well-established ecosystem, provided by an amazing community is constantly writing plug-ins and making them available to install.

We need two specific plug-ins for our app.

- `gatsby-source-filesystem`: This helps us source data from a local file system. Our blogging app is going to source the data from local markdown (\*.md) files, and this plug-in turns them into `File` nodes – which can then be converted into different data types using transformer plug-ins.
- `gatsby-transformer-remark`: As we will be using the markdown files as the data source, we need to convert the File node into a `MarkdownRemark` node so that we can query the HTML representation of the markdown. We will use the `gatsby-transformer-remark` plug-in for that purpose.

## Install Dependencies

You will most probably have installed the `gatsby-source-filesystem` plug-in when creating the basic project structure. Let us now install the rest of the dependencies:

```
yarn add gatsby-transformer-remark lodash react-feather # Or npm i ...
```

We have created our project from the starter project `gatsby-starter-default`. It should have installed `gatsby-source-filesystem` already. You can check it by finding it in the `package.json` file. If you don’t find it installed, please install it manually using the yarn or npm command as shown above.

Also note that we are installing the `lodash` and `react-feather` libraries for the JavaScript object, using array operations and free icons respectively.

## Gatsby Configuration File

Open the `gatsby.config.js` file and perform the following changes:

1. Declare the source and transform plug-in configurations so that the build process knows where to load the source files from and transform them. Add these to the `plugins` array. Here we are telling Gatsby to expect the data source files from the `_data` folder.

```

plugins: [
// ... omitted other things unchanged

{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `markdown-pages`,
    path: `${__dirname}/_data`,
  },
 },
 `gatsby-transformer-remark`,

// ... omitted other things unchanged
]

```

1. Change the value of the `title` property of the `siteMetadata` object to something meaningful. We will provide the name of our app here, i.e. `The Purple Blog.`

```
module.exports = {
  siteMetadata: {
    title: `The Purple Blog`,

  // ... omitted other things unchanged

```

## Gatsby, Markdown and GraphQL

Now, we will create the data source files and query them so that we can use the result on the React components.

Create a folder called `_data` at the root of the project folder, and create a markdown file with the following format:

```
---
date: 2020-05-18
title: What is Life?
tags:
  - soft-skill
  - spirituality
  - life
  - science
author: Matt Demonic
---

> Taken from [Wikipedia]() to dmonstrate an example.

Life is a characteristic that distinguishes physical entities that have biological processes, such as signaling and self-sustaining processes, from those that do not, either because such functions have ceased, or because they never had such functions and are classified as inanimate.

In the past, there have been many attempts to define what is meant by "life" through obsolete concepts such as odic force, hylomorphism, spontaneous generation and vitalism, that have now been disproved by biological discoveries. Aristotle is considered to be the first person to classify organisms. Later, Carl Linnaeus introduced his system of binomial nomenclature for the classification of species. Eventually new groups and categories of life were discovered, such as cells and microorganisms, forcing dramatic revisions of the structure of relationships between living organisms. Though currently only known on Earth, life need not be restricted to it, and many scientists speculate in the existence of extraterrestrial life. Artificial life is a computer simulation or human-made reconstruction of any aspect of life, which is often used to examine systems related to natural life.

Death is the permanent termination of all biological processes which sustain an organism, and as such, is the end of its life. Extinction is the term describing the dying out of a group or taxon, usually a species. Fossils are the preserved remains or traces of organisms.

```

If you are new to markdown file structure, you can [learn it here](https://guides.github.com/features/mastering-markdown/). As the purpose of our app is to create blog articles, we have defined the structure of an article here. Notice that we have the publication date, title, author, tags and finally the content of the article. You can create as many such files as you wish.

At this stage, start the Gatsby development server using the `gatsby develop` command if it is not running already. If it is running, please restart it. Open a browser tab and try the URL [`http://localhost:8000/___graphql`](http://localhost:8000/___graphql). It will open an editor for you to create the desired queries to query data from the source files.

The image below shows three panels. The first is to select the attributes to form a query. The second shows the query formed and allows you to change things manually. The last panel is to show the results.

[![](https://bugfender.com/wp-content/uploads/2021/01/Untitled-3-1024x517.png)](https://bugfender.com/wp-content/uploads/2021/01/Untitled-3.png)<figcaption>Gatsby GraphQL editor for Query</figcaption>

The query formed here is a GraphQL query. We will use queries like this in the reactjs components using Gatsby GraphQL support, which is provided out-of-the-box.

### Gatsby Template and Dynamic Page Creation

You may recall that we have included `tags` among the properties for the blog article. This means that we can show tags for an article and allow blog readers to use them to filter articles.

For example, when we click on the tag `javascript`, we want to list all the articles that have the same tag.. The same applies for any other tags we add.

Also, notice that the URL changes when we click on a tag to filter the articles.

[![](https://bugfender.com/wp-content/uploads/2021/01/tag-flow.gif)](https://bugfender.com/wp-content/uploads/2021/01/tag-flow.gif)<figcaption>Tag Flow – Page changes</figcaption>

With _Gatsbyjs_ you can also create pages, and each of them will create a route (a unique URL) for you automatically.

A page can be created statically simply by creating a file under the `src/pages` directory. The name of the file then becomes the unique URL name. You can also create a page dynamically using templates: this is an extremely powerful concept very apt for the tag use-case we have seen just now.

We have to create a page dynamically for each of the tags, so that it also creates a unique URL, and when an article title is clicked. We have to show the full article content to the user and the unique part of the URL is called `slug`.

To create pages dynamically, open `gatsby-node.js` and add these lines at the top of the file:

```
const path = require(`path`);
const _ = require("lodash");
const { createFilePath } = require(`gatsby-source-filesystem`);

```

Here we are importing required libraries to create the setup for the dynamic page creation.

Next, we will override two Gatsby methods, `onCreateNode` and `createPages`.

### Override `onCreateNode`

We will override this method to create a new node field called `slug,` so that we can use this node in our query later. To create `slug,` add this code snippet after the require statements:

```
//... all require statements

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const slug = createFilePath({ node, getNode, basePath: `pages` })
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
} 

```

### Override `createPages`

Add this code snippet after the onCreateNode method:

```
exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  
  // 1 - Query to all markdown files
  const result = await graphql(`
    query {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
            frontmatter {
              title
              tags
              date
            }
          }
        }
      }
    }
  `);

  const tagSet = new Set();
  
  // 2 - Iterate through the nodes and create pages
  result.data.allMarkdownRemark.edges.forEach((edge) => {
    
    // 3 Create page for each of the node
    createPage({
      path: edge.node.fields.slug,
      component: path.resolve(`./src/templates/blog-post.js`),
      context: {
        // Data passed to context is available
        // in page queries as GraphQL variables.
        slug: edge.node.fields.slug,
      },
    });

    // 4- Generate a list of tags
    if (edge.node.frontmatter.tags) {
      edge.node.frontmatter.tags.forEach(tag => {
        tagSet.add(tag);
      });
    }

    // 5- Generate pages for each of the tags
    tagSet.forEach(tag => {
      createPage({
        path: `/tags/${_.kebabCase(tag)}/`,
        component: path.resolve(`./src/templates/tagged-post.js`),
        context: { tag }
      });
    });
  })
}

```

A few things are going on here:

1. First, we need to create a query that results out in listing all the markdown files. Here we are interested in the `title`, `tags`, `date` and the newly created field, `slug`.
2. The query returns an array of transformed file nodes, each of which contains the information we intended to make queries for. We loop through the array to create the required pages.
3. Create pages for each of the nodes. Here, we are telling the Gatsby build process to use the `blog-post.js` file under the `src/templates` folder to create pages. These pages will be used when our users click on the article title to get to article details.
4. Next, we loop through the tags of all the articles and create a set (which is the unique collection in JavaScript) of unique tags.
5. Create a page for each of the tags. Here, we are telling the Gatsby build process to use the `tagged-post.js` file under the `src/templates` folder to create pages. These pages will be used when our users click on the tag of an article to filter out the articles with the same tag.

We will create both the template files shortly.

## Create Templates and Components

Now we will create a reactjs component to render the article list. Simply create a file called `PostList.js` under the folder `src/components` with the following content. This is a simple react component which loops through each of the post articles and renders them.

```
import React from "react"
 import TagCapsules from "./TagCapsules"
 import { Link } from "gatsby"
 import { User } from 'react-feather'
 import GatsbyBugfender from '../utils/bugfender'
 const Post = props => (
   
     
         {props.details.frontmatter.title} {' '} {props.details.frontmatter.author} {", "} on {props.details.frontmatter.date}     
     {props.details.excerpt}
        
 )
 export default (props) => {
   let posts = props.data.allMarkdownRemark.edges
   if (posts.length > 0) {
     GatsbyBugfender.log(${posts.length} posts found in the repository)
     GatsbyBugfender.sendUserFeedback('Posts created', 'Default Posts created Successfully!')
   } else {
     GatsbyBugfender.sendIssue('No Posts Found')
   }
   return (
     
       {posts.map((post, index) => ( ))}     

   )
 }
```

Next, create a file called `TagCapsules.js` under the same folder. This is a component to create representation for the tags in the article list page.

```
import React from "react"
import _ from "lodash"
import { Link } from "gatsby"

import GatsbyBugfender from '../utils/bugfender'

import styles from "./TagCapsules.module.css"

const Tag = props => {
  const tag = props.tag
  GatsbyBugfender.log(`Recieved Tag ${tag}`)

  return (
    
      
        {tag}
      
    
  )
}

const Tagcapsules = props => {
  const tags = props.tags
  GatsbyBugfender.log(`Recieved ${tags.length} tags`)
  return (
    
      {tags && tags.map(tag => )}
    
  )
}

export default Tagcapsules

```

We will be using some styling to make the tags look better. To do this, create a file called `TagCapsules.module.css` under the same folder, with the following content:

```
.tags {
    list-style: none;
    margin: 0 0 5px 0px;
    overflow: hidden; 
    padding: 0;
  }
  
  .tags li {
    float: left; 
  }
  
  .tag {
    background: rgb(230, 92, 230);
    border-radius: 3px 0 0 3px;
    color: rgb(255, 255, 255);
    display: inline-block;
    height: 26px;
    line-height: 26px;
    padding: 0 20px 0 23px;
    position: relative;
    margin: 0 10px 10px 0;
    text-decoration: none;
  }
  
  .tag::before {
    background: #fff;
    border-radius: 10px;
    box-shadow: inset 0 1px rgba(0, 0, 0, 0.25);
    content: '';
    height: 6px;
    left: 10px;
    position: absolute;
    width: 6px;
    top: 10px;
  }
  
  .tag::after {
    background: #fff;
    border-bottom: 13px solid transparent;
    border-left: 10px solid rgb(230, 92, 230);
    border-top: 13px solid transparent;
    content: '';
    position: absolute;
    right: 0;
    top: 0;
  }
  
  .tag:hover {
    background-color: rgb(143, 4, 224);
    color: white;
  }
  
  .tag:hover::after {
     border-left-color: rgb(143, 4, 224); 
  }

```

Now we will create both the template files. Create a folder called `templates` under the `src` folder and create the file `blog-post.js`, using the content below. Please note the query at the end of the file: it queries the title and the content for a post article, and renders that. This is the page to show when a user clicks on the title of an article to see the details.

```
import React from "react";
 import { graphql } from "gatsby";
 import SEO from "../components/seo"
 import Layout from "../components/layout";
 export default ({ data }) => {
   const post = data.markdownRemark
   return (
                       
             {post.frontmatter.title}
                      
     
   )
 }
 export const query = graphql`
   query($slug: String!) {
     markdownRemark(fields: { slug: { eq: $slug } }) {
       html
       frontmatter {
         title
       }
     }
   }
```

Now it’s time to create another template. Create a file called `tagged-post.js` under `src/template` folder, using the following content. Here we make a query for all the posts that match a particular tag. Then we pass the matched post array to the `PostList` component we have already created.

```
import React from "react";
import { graphql } from "gatsby";
import Layout from "../components/layout";
import PostList from '../components/PostList';

export default ({data}) => {
    console.log(data);
    return (
      
        
          
        
      
    )
};

export const query = graphql`
  query($tag: String!) {
    allMarkdownRemark(
      sort: { fields: [frontmatter___date], order: DESC }
      filter: { frontmatter: { tags: { in: [$tag] } } }
      ) {
      totalCount
      edges {
        node {
          id
          frontmatter {
            title
            date(formatString: "DD MMMM, YYYY")
            tags
          }
          fields {
            slug
          }
          excerpt
        }
      }
    }
  }
`

```

Now, the last thing is to change the `index.js` page so that our home page shows all the articles. Open the index.js file and replace the content with the following. Here, we are querying all the post articles and passing the array as a props to the `PostList` component.

```
import React from "react"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { graphql } from "gatsby"

import GatsbyBugfender from '../utils/bugfender'

import PostList from '../components/PostList'

GatsbyBugfender.init({
  appKey: 'YOUR_BUGFENDER_APP_KEY',
});

const IndexPage = ({data}) => (
  
    
    
  
)

export default IndexPage

export const GET_ALL_POSTS = graphql`
  {
    allMarkdownRemark (
      sort: { fields: [frontmatter___date], order: DESC }
      ){
      edges {
        node {
          id
          frontmatter {
            title
            tags
            date(formatString: "DD MMMM, YYYY")
            author
          }
          html
          excerpt
          fields {
            slug
          }
        }
      }
    }
  }
`

```

All you need to do is replace the `YOUR_BUGFENDER_APP_KEY` in the above code with the app key you created while setting up the Bugfender app. Cool, right?

Now, restart `gatsby develop` if it is running already. You can access the app with the URL `http://localhost:8000` to see it running successfully.

[![](https://bugfender.com/wp-content/uploads/2021/01/flow.gif)](https://bugfender.com/wp-content/uploads/2021/01/flow.gif)<figcaption>The completed application</figcaption>

## Deploy it on Netlify

The app is running successfully on localhost. Let’s make it accessible to users by hosting it on a CDN. While doing that, we will also set up a continuous integration and deployment (CI/CD) so that a build-and-deploy kicks off with the code changes pushed to the Git repository.

The [Ne](https://www.netlify.com/)[t](https://www.netlify.com/)[lify](https://www.netlify.com/) platform enables us to do this easily. [Create an account](https://app.netlify.com/signup?_ga=2.184276710.197514430.1608520053-377647057.1589700197) with Netlify and log in to the application using the web interface. Now follow the steps mentioned below to deploy the app on Netlify with the CI/CD enabled by default.

Make sure to commit and push all the source code to the GitHub repository. You can create a new site with Netlify simply by selecting your GitHub repository.

[![](https://bugfender.com/wp-content/uploads/2021/01/deploy_1-1024x585.png)](https://bugfender.com/wp-content/uploads/2021/01/deploy_1.png)<figcaption>Select the GitHub Repository</figcaption>

In the next step, provide the build settings as shown in the image below.

[![](https://bugfender.com/wp-content/uploads/2021/01/deploy_2-1024x986.png)](https://bugfender.com/wp-content/uploads/2021/01/deploy_2.png)<figcaption>Build Settings</figcaption>

A build will be initiated automatically once the steps are completed. Please wait for the build to finish successfully. In case of an issue, you can consult the build logs for more details.

[![](https://bugfender.com/wp-content/uploads/2021/01/deploy_3.png)](https://bugfender.com/wp-content/uploads/2021/01/deploy_3.png)<figcaption>Build in-progress</figcaption>

Netlify creates a site for you with a random name. However, you can change it as per your choice based on availability.

[![](https://bugfender.com/wp-content/uploads/2021/01/deploy_4.png)](https://bugfender.com/wp-content/uploads/2021/01/deploy_4.png)<figcaption>Give a suitable site name</figcaption>

That’s it! Now the app will be available using the URL that appears below the site name field. In my case, it is [https://gatsby-bugfender.netlify.app](https://gatsby-bugfender.netlify.app)

## Inspecting with Bugfender

You can inspect the logs from the Bugfender web console. As it starts collecting the logs, you can find them for each of your devices. In our case, it is a web application. Hence the device is the browser you have used to access the app.

[![](https://bugfender.com/wp-content/uploads/2021/01/bf_1-1024x90.png)](https://bugfender.com/wp-content/uploads/2021/01/bf_1.png)<figcaption>Bugfender log details for a device</figcaption>

You can drill into and see the logs collected for a specific timeframe. In the image below, it shows the logs along with the user feedback created when a post is successfully published in our app.

[![](https://bugfender.com/wp-content/uploads/2021/01/bf_2-1024x336.png)](https://bugfender.com/wp-content/uploads/2021/01/bf_2.png)<figcaption>Logs Drill-Down</figcaption>

It is also easy to spot the errors.

[![](https://bugfender.com/wp-content/uploads/2021/01/bf_3-1024x145.png)](https://bugfender.com/wp-content/uploads/2021/01/bf_3.png)<figcaption>Errors</figcaption>

You can find issues, crashes, etc. under the respective tabs. In the screenshot below, we see an issue has been created as no article posts are found.

[![](https://bugfender.com/wp-content/uploads/2021/01/bf_4-1024x182.png)](https://bugfender.com/wp-content/uploads/2021/01/bf_4.png)<figcaption>Issues</figcaption>

You can drill-down to the issue and send it to the GitHub for further triaging.

[![](https://bugfender.com/wp-content/uploads/2021/01/bf_5-1024x148.png)](https://bugfender.com/wp-content/uploads/2021/01/bf_5.png)<figcaption>Send Issue to GitHub</figcaption>

Please explore the Bugfender app further for all the other options.

# Before we go…

Bugfender is a tool that helps you finding errors in your production apps. We strongly believe in sharing knowledge and that’s why we create articles like this one. If you liked it, help us to continue creating content by sharing this article or [signing up in Bugfender](https://dashboard.bugfender.com/signup).