Web / Next.js 9 min read Updated Aug 2026

Build a Fast 4K Wallpaper Web App in Next.js & React with NexWall API

Complete tutorial to build a high-performance wallpaper website with Next.js App Router, React Server Components, Tailwind CSS, and NexWall JSON API.

1. Fetching Wallpapers in Next.js Server Components

Using Next.js 14+ App Router, you can fetch high-resolution 4K wallpapers on the server with automated caching and ISR:

// app/wallpapers/page.tsx
interface Wallpaper {
  id: number;
  category_id: number;
  image_url: string;
  thumbnail_url: string;
  resolution: string;
}

async function getWallpapers(categoryId?: number): Promise<Wallpaper[]> {
  const url = new URL('https://nexwall.kodnextech.com/api/developer/v1/wallpapers');
  url.searchParams.set('per_page', '30');
  if (categoryId) url.searchParams.set('category_id', categoryId.toString());

  const res = await fetch(url.toString(), {
    headers: {
      'Authorization': `Bearer ${process.env.NEXWALL_API_KEY}`,
      'Accept': 'application/json',
    },
    next: { revalidate: 3600 } // Cache at edge for 1 hour
  });

  if (!res.ok) throw new Error('Failed to fetch wallpapers');
  const json = await res.json();
  return json.data;
}

2. Responsive Masonry Grid UI Component

Display the wallpapers with smooth hover effects, Next/Image optimization, and category pill navigation:

// components/WallpaperGrid.tsx
import Image from 'next/image';

export default function WallpaperGrid({ wallpapers }: { wallpapers: Wallpaper[] }) {
  return (
    <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 p-4">
      {wallpapers.map((w) => (
        <div key={w.id} className="group relative aspect-[9/16] rounded-2xl overflow-hidden bg-slate-900 border border-white/10 shadow-lg">
          <Image
            src={w.thumbnail_url}
            alt="4K Wallpaper"
            fill
            sizes="(max-width: 768px) 50vw, 25vw"
            className="object-cover group-hover:scale-105 transition-transform duration-300"
            loading="lazy"
          />
          <div className="absolute inset-0 bg-gradient-to-t from-black/80 via-transparent opacity-0 group-hover:opacity-100 transition-opacity p-4 flex items-end justify-between">
            <span className="text-xs font-bold text-white bg-accent/80 px-2 py-1 rounded-lg">{w.resolution}</span>
            <a href={w.image_url} target="_blank" download className="text-xs font-bold bg-white text-black px-3 py-1.5 rounded-lg">
              Download 4K
            </a>
          </div>
        </div>
      ))}
    </div>
  );
}

Want to test this endpoint right now?

Use the interactive Live Sandbox Console to test queries without writing code.

Try In Sandbox