Unlock seamless workflows and faster delivery with our latest releases - Join the deep dive

Trouble deploying Next JS & Vercel blogs page, resolved using Sanity Client.

20 replies
Last updated: Jul 22, 2021
Hey guys, I'm kind of having some trouble with deploying my blogs page using
Next JS & Vercel
. The
blogs page & [Slug] page
runs absolutely fine on 
localhost:3000
 but throws an error on a deployed website 
500 | Internal Server Error
, You can have a look here In case If you want to 
<https://www.mahijendra.dev/>
. I'm not sure know what I'm doing wrong here.

This is my pages/blog.js code
 
import React, { useState, useEffect } from "react";
import imageUrlBuilder from "@sanity/image-url";
import { sanityClient } from "../lib/sanityClient";
import PostCard from "../components/PostCard"
import MainNav from "../components/MainNav";
import BlogCard from "../components/BlogCard";

const Blog = ({ posts }) => {
    const [header] = useState({
        mainHeader: "BLOGS",
        subHeading: "My Blogs",
        text:
            "Blah Blah"
    });

    const [mappedPosts, setMappedPosts] = useState([]);

    useEffect(() => {
        if (posts.length) {
            const imageBuilder = imageUrlBuilder(sanityClient);

            setMappedPosts(
                posts.map((post) => {
                    return {
                        ...post,
                        mainImage: imageBuilder
                            .image(post.mainImage)
                            .width(450)
                            .height(500),
                    };
                })
            );
        } else {
            setMappedPosts([]);
        }
    }, [posts]);

    return (
        <>
           <MainNav />

            <div className="common">
                <h3 className="font-semibold text-customGreen py-3 pt-12 tracking-wide font-nunito">{header.mainHeader}</h3>
                <h1 className="font-bold lg:text-3xl text-customGreen tracking-wide font-nunito">{header.subHeading}</h1>
                <p className="font-normal lg:text-md text-customGreen tracking-wide font-nunito">{header.text}</p>
                <div className="commonBorder"></div>
            </div>

            <div className="pt-16 pb-6 px-4 sm:px-6 lg:pt-8 xl:mx-48" >
                <div className="">
                    {mappedPosts &&
                    mappedPosts.length &&
                    mappedPosts.map((post, index) => (
                        <BlogCard data={post} key={index} />
                    ))}
                </div>
            </div>
        </>
    );
};

export const getServerSideProps = async (context) => {
    const query = encodeURIComponent(`*[ _type == "post" ]`);
    const url = `${process.env.SANITY_URL}query=${query}`;

    const data = await fetch(url).then((res) => res.json());
    const posts = data.result;

    if (!posts || !posts.length === 0) {
        return {
            props: {
                posts: [],
            },
        };
    } else {
        return {
            props: {
                posts,
            },
        };
    }
};

export default Blog
And the SANITY_URL stands for this which is located in my
.env.local

SANITY_URL = <https://projectID.api.sanity.io/v2021-06-07/data/query/production>?

And the error that I keep seeing on
vercel realtime logs
is

[GET] /blog

2021-07-22T11:08:58.538Z	3f8b63af-f76f-47d6-b88f-dbeb20a4cf52	ERROR	TypeError: Only absolute URLs are supported
    at getNodeRequestOptions (/var/task/node_modules/node-fetch/lib/index.js:1305:9)
    at /var/task/node_modules/node-fetch/lib/index.js:1410:19
    at new Promise (<anonymous>)
    at fetch (/var/task/node_modules/node-fetch/lib/index.js:1407:9)
    at getServerSideProps (/var/task/.next/server/pages/blogNew.js:250:22)
    at renderToHTML (/var/task/node_modules/next/dist/next-server/server/render.js:39:221)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async /var/task/node_modules/next/dist/next-server/server/next-server.js:112:97
    at async /var/task/node_modules/next/dist/next-server/server/next-server.js:105:142
    at async Server.renderToHTMLWithComponents (/var/task/node_modules/next/dist/next-server/server/next-server.js:137:387)
RequestId: 3f8b63af-f76f-47d6-b88f-dbeb20a4cf52 Error: Runtime exited with error: exit status 1
Runtime.ExitError

[GET] /robots.txt
robots.txt
2021-07-22T10:51:22.797Z	9fb2b9e1-9155-49d1-af6a-82b43494503c	ERROR	TypeError: Only absolute URLs are supported
    at getNodeRequestOptions (/var/task/node_modules/node-fetch/lib/index.js:1305:9)
    at /var/task/node_modules/node-fetch/lib/index.js:1410:19
    at new Promise (<anonymous>)
    at fetch (/var/task/node_modules/node-fetch/lib/index.js:1407:9)
    at getServerSideProps (/var/task/.next/server/pages/[slug].js:416:22)
    at renderToHTML (/var/task/node_modules/next/dist/next-server/server/render.js:39:221)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async /var/task/node_modules/next/dist/next-server/server/next-server.js:112:97
    at async /var/task/node_modules/next/dist/next-server/server/next-server.js:105:142
    at async Server.renderToHTMLWithComponents (/var/task/node_modules/next/dist/next-server/server/next-server.js:137:387)
RequestId: 9fb2b9e1-9155-49d1-af6a-82b43494503c Error: Runtime exited with error: exit status 1
Runtime.ExitError
Jul 22, 2021, 12:16 PM
It's much easier to write code with Sanity Client. I'd recommend using that instead of 'fetching' a URL

https://www.sanity.io/docs/js-client
Create the instance of the client and use it's fetch method to execute GROQ queries.
More about GROQ Queries here:
https://www.sanity.io/docs/query-cheat-sheet
Jul 22, 2021, 12:28 PM
I think the issue with your URL is that it does not have a '?' symbol before parameters. Creating a URL can be error prone, and therefore it's better to go for the Sanity Client
Jul 22, 2021, 12:31 PM
Alright sure I'll give it a try using Sanity client. Thank you!
Jul 22, 2021, 12:39 PM
Yeah I did deploy
Jul 22, 2021, 6:25 PM
user T
How's things going? did you try Sanity Client?
Jul 22, 2021, 6:27 PM
Previously until yesterday I was using
ServerSideProps
to fetch the data. Now I Switched to
sanityClient
as User suggested.
Jul 22, 2021, 6:28 PM
ServerSideProps is for server-side rendering. If you want server side rendering, you have to fetch using sanity client, inside ServerSideProps
Jul 22, 2021, 6:30 PM
Yeah okay. It keeps throwing me this error
ReferenceError: slug is not defined
How do I declare this using Next JS?

import React, {useState, useEffect} from "react";
import imageUrlBuilder from "@sanity/image-url";
import MainNav from "../components/MainNav";
import Link from "next/Link"
import BlogCard from "../components/BlogCard";
import sanityClient from "../lib/client"

const Blog = ({posts, props}) => {
    const [header] = useState({
        mainHeader: "BLOGS",
        subHeading: "My Blogs",
        text:
            "I am a developer, primarily active in the Hashnode community as a blogger. I like writing about web development on my blog."
    });
    const [mappedPosts, setMappedPosts] = useState([]);

    useEffect(() => {
        sanityClient
            .fetch(`*[_type == "post"]{
            title,
            slug,
            mainImage{
            asset-> {
                _id,
                url
              },
             alt
            }
        }`)
            .then((data) => setMappedPosts(data))
            .catch(console.error);
    }, [])

  
    return (
        <>
            <MainNav/>
            <div className="common">
                <h3 className="font-semibold text-customGreen py-3 pt-12 tracking-wide font-nunito">{header.mainHeader}</h3>
                <h1 className="font-bold lg:text-3xl text-customGreen tracking-wide font-nunito">{header.subHeading}</h1>
                <p className="font-normal lg:text-md text-customGreen tracking-wide font-nunito">{header.text}</p>
                <div className="commonBorder"></div>
            </div>


            <div className="pt-16 pb-6 px-4 sm:px-6 lg:pt-8 xl:mx-48">
                <div className="">
                    {mappedPosts &&
                    mappedPosts.length &&
                    mappedPosts.map((post, index) => (
                        <Link href={"/"}  to={"/post/" + post.slug.current} key={post.slug.current} passHref>
                            <div key={index}>
                                <div className="pt-4 pb-4 px-4 sm:px-6 lg:pt-4 lg:pb-4">
                                    <div className="relative max-w-2xl mx-auto divide-y-2 divide-gray-200 lg:max-w-3xl flex justifyCenter">
                                        <div
                                            className="grid gap-16 lg:gap-x-5 lg:gap-y-8 px-12 py-8 shadow-xl overflow-hidden md:max-w-2xl mt-5 transform hover:scale-105 duration-500 ease-in-out">
                                            <div key={post.title}>
                                                <a href={slug} className="mt-2 block">
                                                    <p className="text-2xl font-semibold font-quicksand text-customGreen">{post.title}</p>
                                                    <p className="mt-3 text-sm font-medium tracking-wide  font-quicksand text-lightGreen ">{post.content}</p>
                                                    <p className="mt-3 lg:mt-6 text-sm text-lightGreen font-quicksand tracking-wide italic">{post.publishedAt} | {post.description}</p>
                                                </a>
                                            </div>
                                        </div>
                                    </div>
                                </div>

                            </div>
                        </Link>
                    ))}
                </div>
            </div>
        </>
    );
};

export default Blog

Jul 22, 2021, 6:43 PM
Yeah alright. I catch your drift
Jul 22, 2021, 6:47 PM
Is this the right way to define your
slug
in the blogs page?
    const router = useRouter()
    const { slug } = router.query
Jul 22, 2021, 6:49 PM
router.pathname will give you the slug
Jul 22, 2021, 6:50 PM
How do I get the pathname here?
Jul 22, 2021, 6:51 PM
router.pathnamethats enough
Jul 22, 2021, 6:51 PM
oh you're trying to get the slug for [slug].js?
Jul 22, 2021, 6:51 PM
yeah exactly, to the blogs page
Jul 22, 2021, 6:52 PM
Jul 22, 2021, 6:52 PM
When I'm using
router.query
, It's redirecting me to the main page I mean to
localhost:3000
on click on the blog or an article
Jul 22, 2021, 6:53 PM
Please refer to the link I shared
Jul 22, 2021, 6:54 PM
Yeah I actually read this one. And also the Migrating from react router to Next Js one
Jul 22, 2021, 6:56 PM
I'm still not able to fetch the data, I mean
slug
. Not sure what I'm doing wrong
Jul 22, 2021, 7:09 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?