code snippets

Fetching Data on the Server - Next.js


With Next.js 15 and React server components you can now load all of your server/database/API/password details into your file without fear of blowing yourself up. Back in the 'bad-old-days' (when everything ran on the client) you needed to break out your API calls and credentials into a .env file and then make your call from a useEffect() block. Well no mas! The code below is a convenient server component so the file is run and parsed on the server and the results get downloaded to the client.

1// A helper function to fetch the blog data
2async function fetchBlogs() {
3    //the handy-dandy Promise that resolves after 2 seconds
4    //await new Promise((resolve) => setTimeout(resolve, 2000));
5    const res = await fetch('https://api.vercel.app/blog', { cache: 'no-store' }); // Adjust caching as needed
6    if (!res.ok) {
7        throw new Error('Failed to fetch blogs');
8    }
9    return res.json();
10}
11
12// Function to render blogs (calls fetchBlogs() above)
13async function BlogList() {
14    const posts = await fetchBlogs();
15
16    return (
17        <ul className="space-y-2 p-2">
18            {posts.map((post: Post) => (
19                <li key={post.id}  className="p-2 bg-white shadow-md rounded-lg">&middot; {post.title}</li>
20            ))}
21        </ul>
22    );
23}
24
25// Exported default function to display blogs. Wrapped in suspense tags in case it takes a while
26export default function Page() {
27    
28    return(
29        <Suspense fallback={<div>Loading blogs...</div>}>
30            {/* BlogList is an async component */}
31            <BlogList/>
32        </Suspense>
33    );
34}
35
36//...for good measure, here is my error.ts file to satisfy an errorBoundary
37'use client';
38
39export  function Error({ error, reset }: { error: Error; reset: () => void }) {
40    return (
41        <div>
42            <h2>Something went wrong!</h2>
43            <p>{error.message}</p>
44            <button onClick={() => reset()}>Try again</button>
45        </div>
46    );
47}

This bulleted list is the result of the fetch call above. It really works!


Loading blogs...

Summary: fetchBlogs() calls the api.vercel.app/blog endpoint, checks for errors then converts the response to json() for return to BlogList(). In the return output a simple .map() statement loops over the results and outputs to screen. The function Page() wraps the functionality in a suspense tag in case network ops are slowed.... Don't forget to add a key attribute to each item being output in your map loop; React needs that for element id for future operations. Oh, and just in case something naughty happens I included an error.ts file that I simply added to the same directory with the other files. We don't need a loading.tsx page since we're already using <Suspense /> with a fallback attribute.