Array map to new type in TypeScript

How to array map to a different type in Typescript


In my recent Nextjs project, need to shape object array to a different type.

Mapping through the entire array in my arrow function and return the new object.

Even though the return statement work. The type is still unknown. So, I have to covert the result into array of my type.

Mapping Array Type

export type LatestInvoiceType={
id:number;
amount: number;
customer:{
name:string;
email:string;
image_url:string;
}
}

New Type

 export type LatestInvoice = {

id: string;
name: string;
image_url: string;
email: string;
amount: string;
};

Solution to the problem

Here is my solution to the problem

    const latestInvoices  = invoices.map(invoice =>  {
      return{
      id:invoice.id.toString(),
      amount:invoice.amount.toString(),
      name:invoice.customer?.name,
      email:invoice.customer?.email,
      image_url:invoice.customer?.image_url
      };
    }) as LatestInvoice[] ;

Create a dark mode theme switch in Nextjs 13

How to add dark theme capability in Nextjs app using next-themes


Creating React powered JavaScript application using Nextjs is easy. This example utilizes the experimental features of Nextjs 13.

I assume that you have Nextjs project ready in hand, otherwise follow the Next 13 app setup guide.

Theming the App

For theming I have been using Tailwind and for dark theme we can use a minimal library, next-themes.

Install the library using yarn or npm

$ npm install next-themes
# or
$ yarn add next-themes 

Theme Provider

First up all we need a theme provider component to pass the theme to all the component in app (experimental feature appDir of Nextjs 13) folder.

'use client'

import { ThemeProvider } from 'next-themes'

export function Providers({ children }) {
  return <ThemeProvider attribute="class">{children}</ThemeProvider>
}

Here we used the ThemeProvider of next-themes for applying the theme.

Note that we should mark the component as client component.

In Nextjs appDir feature will set all component sever side components by default.

Tailwind configuration

When we using Next-Theme with Tailwind we may need to use the Tailwind dark theme, so we can use TW class.

 /** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx}",
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
 
    // Or if using `src` directory:
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
  darkMode: 'class'
}

Root Layout

In the root layout we can wrap the body of the app with the Provider.

Theme Switcher

We need a component for switching between Light and Dark theme.

'use client'
import { useState, useEffect } from "react";
import { useTheme } from "next-themes";
import { SunIcon } from "@heroicons/react/outline";

const ThemeSwitch = () => {
  const [mounted, setMounted] = useState(false);
  const { theme, setTheme } = useTheme();
  // useEffect only runs on the client, so now we can safely show the UI
  useEffect(() => {
    setMounted(true);
  }, []);

  if (!mounted) {
    return null;
  }
  

  return (
    <div className="inline-flex items-center">
      <SunIcon className="w-4 h-4 mr-2" />
      <select
        name="themeSwitch"
        value={theme}
        onChange={e =>setTheme(e.target.value)}>
        <option value="system">System</option>
        <option value="dark">Dark</option>
        <option value="light">Light</option>
      </select>
    </div>
  );
};

Using the useTheme hook and setTheme method we can change the theme, easily from any component.

Not found page UI in Nextjs 13

Setup a Not Found Page Nextjs 13


Nextjs 13 comes with lots of experimental features, one of them was the appDir. Let’s talk about the setup a not found page.

Suppose we want to show not found page for the non-existing route. Nextjs allow you to define a custom Not Found page in app directory.

Create a not-found.jsx/tsx file in the route path and export a component with some cool UI and that’s it.

Each time a wrong path is navigated, the page will show up.

//posts/loading.jsx
export default  function Loading() {
 
  return(
<div>
Data is loading 
</div>
  )
}

Implementing a loading UI in Nextjs 13

Loading UI in Nextjs


Nextjs 13 comes with lots of experimental features, one of them was the appDir. Let’s talk about the loading UI.

Suppose we want to show some UI, may be some cool spinner while data is fetching from the server.

Usually, such UI can be implemented by checking the loading status or wrapping the JSX within a suspense block.

In Next’s latest version they have provided a loading UI, which handle the task.

Create loading.jsx file in the route and export a default component. The loading component will render while data is fetching. No additional coding is required.

//posts/loading.jsx
export default  function Loading() {
 
  return(
<div>
Data is loading 
</div>
  )
}

How to fetch data in Nextjs 13 appDir

How to fetch data in Next 13 app route


Nextjs 13 comes with lots of experimental features, one of them was the appDir. Let’s talk about the data fetching in Nextjs 13.

In the older version we have fetched data in Next app with static props function and passes it down to component as props.

Things have been changed a lot. In appDir data fetching is done at server side and will be available to client. It also improvises the performance.

Do you know that, in Next 13 we can create client and server components. ?

GetData

Define a getData function at the route (page.jsx) and use it in the home component as follows



async function getData() {

  const res = await client.fetch(
    `*[_type == "post"]{title,_createdAt,slug,_id,summary,featured_image} | order(_createdAt desc)`
  );
  const data = await res;
  return data;
}

export default async function Home() {
 
  const posts = await getData();    

How to use Turbopack build tool in Nextjs project

How to use Turbopack the fastest web build tool made with Rust and 😍


Turbopack is the fastest Vercel’s web build tool made with Rust and it smarter than Vitejs which is used in React, Vue and SvelteKit.

Turbopack currently available for Nextjs only.

How do we enable Turbo in Nextjs project. Can try in two methods.

Use a –turbo option in dev script.

 "dev": "next dev --turbo", 

For using old projects there is another way.

Create a turbo.json file in the root of the project with following

//turbo.json
{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "outputs": [".next/**"]
    },
    "lint": {
      "outputs": []
    }
  }
}

Then we can use the turbo dev command as follows

npx turbo dev

[display-posts tag=nextjs

Try Next 13 experimental App feature

How to create a Nextjs project with experimental appDir feature


Recently Nextjs has introduced new features including a app routing system in version 13, which can be found other frameworks such as SvelteKit.

One of the replacement on both frameworks is that of the index file from the routes to page.jsx / +page.svelte respectively.

How to create Nextjs 13 project with app feature ?

To create a Nextjs 13 project with new features which is run under beta, have to use the experimental-app flag.

npx create-next-app@latest --experimental-app

Try my new blog built with Svelte and sanity

Integrate contentful CMS in Nextjs

How to integrate contentful headless cms in Nextjs


Adding Contentful CMS to Nextjs require a different approach.

The Client

Create and export the client and then we can use the module to make calls to the API.

npm i contentful 
import {createClient} from 'contentful'

const client=createClient({
    space:'space 🆔 ',
    accessToken:'api-token'
});


export {client}

Nextjs API

I tried to directly using the client in app, but it doesn’t work for me. So have to create a internal API.

Under pages/api/posts create two route, one for all posts and another for dynamic / individual posts.

// index.js
import {client} from "../../../contentful";

export default async function  index(req, res) {
    const r = await  client.getEntries();
    return  res.status(200).json(r)
}

import {client} from "../../../contentful";
export default async function  id(req, res) {
    const
    {
        id
    } = req.query;

    const r = await  client.getEntry(id);
    return  res.status(200).json(r)
}

try to access the the API https:// localhost:3000/api/posts

In the route and components

In the Nextjs route / component, as usual we can fetch data in getStaticProps as follows and pass it to the component. The fetching will run on the top.

import PostGrid from "../Components/PostGrid";
import {GridSkelton} from "../Components/Skeltons";

export async function getStaticProps(context) {
  const res =  await fetch('http:localhost:3000/api/posts')
  const posts =   await res.json() ;
  return {
    props: {
      data:posts ,
    }
  }
}
export default  function Home({data}) {
  return (
      <div >
        {/*{JSON.stringify(data)}*/}
        {data ? <PostGrid  posts={data.items}  />:<GridSkelton/> }
      </div>
  )
}
 

Dynamic route

For dynamic route, we have to configure the staticpaths too. This will help static generation.

//pages/posts/[id].js 

import { useRouter } from 'next/router'
import SinglePost from "../../Components/SinglePost";
import {GridSkelton} from "../../Components/Skeltons";

export async function getStaticPaths() {
    const res= await  fetch('http:localhost:3000/api/posts')
    const posts =   await res.json() ;

    const paths = posts.items.map((post) => ({
        params: { id: post.sys.id },
    }))
    return {
        paths,fallback: true // false or 'blocking'
    };
}

export async function getStaticProps({params}) {
    console.log(params)
    const res =  await fetch(`http:localhost:3000/api/posts/${params.id}`)
    const post =  await res.json() ;
    return {
        props: {
            post:post ,
        }
    }
}
const Post = ({post}) => {
    const router = useRouter()
    const { pid } = router.query

    return <>
        { post ? <SinglePost post={post}/>:<GridSkelton/>}
    </>
}

export default Post

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] 🚀

Editor frameworks for JS apps

About Javascript Editor frameworks


If you are building content based application such as blog, may want featured editor, such as Post editor or comment box. Making such an editor with all formatting capabilities would be tiresome.

Editor frameworks and wrapper libraries help us achieve this goal with ease and peace. I don’t intended to review each of these , instead I would to list best of them and in the up coming posts we will learn using these awesome editor frameworks.

My Picks

I like block editor mostly for content management, in my react app I will choose the Editor.js . It is easy to configure and use.

Second most useful framework for content management is Drftjs , which is maintained by Facebook itself. It is a complete Editor framework featuring mention, hashtag etc and it’s flexible too.

Here is complete list of framework available for building a full featured editor in your next JS / React/Vue/Angular app