We had tried blog with Nuxt 3 and the Solidjs and it is 😎. If you miss the guide here it is.
- How to build a blog using Nuxt 3 and Graphql - How to build a blog app using TailwindCSS + Nuxt 3 + Graphql API
- How to build a blog with Solidjs - How to create blog application using mocked graphql API and Solidjs front end framework
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.
- How to enable tailwind for Nextjs components ? - How to enable tailwindcss for components in Nextjs
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] 🚀