How to build a blog using Tailwind + Graphql + Nextjs

Create blog front end using React-Nextjs and Urql – Graphql


We had tried blog with Nuxt 3 and the Solidjs and it is 😎. If you miss the guide here it is.

About the blog and How ?

Let’s build the same blog using Nextjs and the URQL + TailwindCSS. The backend for the app can be from a graphql API , and in this project we used mockend (we can create a mockend Graphql API using mockend and Github )

Here is what we working on .

  • Dynamic route
  • Mockend API
  • Custom 404 component
  • Category Title transition
  • URQL – Graphql client
The complete source code can be found on GitHub , feel free to fork and share.

The Project Structure

The project structure

TailwindCSS

First thing we need to setup is the TailwindCSS which help us to create responsive CSS using the utility classes.

Here is further guide on Tailwind on Nextjs in case require.

Pages

We nee a set of pages and dynamic route for posts and category posts. In Nextjs we can easily setup pages/route under pages directory.

404

The 404 page can be setup as a route that match all, any non existing route/page.

Under the page directory create […].js with default export

import React from 'react'
import PNF from '../Components/PNF'
export default function ErrorPage() {
  return (
    <PNF/>
  )
}
  

Here PNF is beautiful animated PageNotFound component, we just created in the component directory.

Using useRouter/next/router, we can access the params of dynamic route.

Dynamic route

Layout

Our blog uses single layout, so we go with a Layout component which define Navbar and footer and a content area and implement the layout in the _app.js as follows.

//Layout.js

import Nav from './Nav'
export default function Layout({children}) {
    return (
      <>         
        <div className="bg-gray-100">
          <Nav />
          <div className=" items-center overflow-auto h-screen">
           <main> {children}</main>
          </div>
        </div>
      </>
    );
  }

//_app.js
....
function MyApp({ Component, pageProps }) {
  return (
    <Provider value={client}>
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </Provider>
  )
}
 

The Layout component saved under the components folder.

Components

We need a set of components to serve in the routes. So lets build it.

The components structure.

I don’t want to pull all the code here.. Here is the code page. Copy and paste it to your components 📂.

Fetching the posts

For querying the data I prefer the URQL library which provides hook for querying data.

Setup Urql

Install the dependency

 yarn add urql graphql 

Also need to configure some next-config

 publicRuntimeConfig: {
    GQL_HOST:'https://mockend.com/manoj-ap/mockbackend/graphql',
    NAV_MENU:[{caption:"Home",path:"/"},{caption:"Blog",path:"/post"},{caption:"Category",path:"/category"},{caption:"About",path:"/About"}],
  } 

You may also note that the NAV_MENU, it is rendered in the Nav component. We can add menu to the list and nav will render it.

Dynamic Menu [nav]

Let’s setup Urql for our project in _app.js using the next-config settings.

import Layout from '../Components/Layout'
import '../styles/globals.css'
import { createClient, Provider } from 'urql';
import getConfig from 'next/config'
const {  publicRuntimeConfig } = getConfig()
const client = createClient({
  url: publicRuntimeConfig.GQL_HOST,
});
function MyApp({ Component, pageProps }) {
  return (
    <Provider value={client}>
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </Provider>
  )
}

export default MyApp
 

We wrap the component with Provider so that the entire component tree can use the client.

Querying data

In the index we can query the list of posts as follows

import PostGrid from '../components/PostGrid'
import { useQuery } from 'urql';
import { GridSkelton } from '../Components/Skeltons';
import { useEffect, useState } from 'react';
export default function Home() {
  const query = ` query {
    posts {
      createdAt
      title
      id
      excerpt
      featured_image
    }
  }`;
  
  const [result, reexecuteQuery] = useQuery({
    query: query,
  });
  const { data, fetching, error } = result; 
  return (
    <div  >
              
          {data ? <PostGrid  posts={data.posts}  />:<GridSkelton/> }  
    </div>
  )
}
 

I thing we are almost done. Anything left unclear to 🧒?. Let me know. I will -[…code] 🚀

Author: Manoj

Developer and a self-learner, love to work with Reactjs, Angular, Node, Python and C#.Net

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.