Google Drive image display fails in frontend application

Google Drive Image Display Issue

I have a working system that uploads files to Google Drive through their API and sets proper public permissions. Although the upload works smoothly and I can view the files in my Drive folder, displaying these images in my React frontend leads to crashes.

Backend Upload Code

import { google } from "googleapis";
import { NextRequest, NextResponse } from "next/server";
import { Readable } from "stream";

const SPREADSHEET_ID = process.env.SPREADSHEET_ID!;
const CLIENT_EMAIL = process.env.CLIENT_EMAIL!;
const PRIVATE_KEY = process.env.PRIVATE_KEY!.replace(/\\n/g, "\n");
const FOLDER_ID = process.env.FOLDER_ID!;

export async function POST(request: NextRequest) {
  try {
    const data = await request.formData();
    const username = data.get("username") as string;
    const userEmail = data.get("userEmail") as string;
    const userMessage = data.get("userMessage") as string;
    const uploadedFile = data.get("image") as File | null;

    if (!username || !userEmail || !userMessage) {
      return NextResponse.json({ error: "Required fields missing" }, { status: 400 });
    }

    const authentication = new google.auth.JWT(
      CLIENT_EMAIL,
      undefined,
      PRIVATE_KEY,
      [
        "https://www.googleapis.com/auth/spreadsheets",
        "https://www.googleapis.com/auth/drive",
      ]
    );

    const sheetsApi = google.sheets({ version: "v4", auth: authentication });
    const driveApi = google.drive({ version: "v3", auth: authentication });

    let photoUrl = "";

    if (uploadedFile && uploadedFile.size > 0) {
      const fileBuffer = Buffer.from(await uploadedFile.arrayBuffer());

      const uploadResult = await driveApi.files.create({
        requestBody: {
          name: uploadedFile.name,
          parents: [FOLDER_ID],
        },
        media: {
          mimeType: uploadedFile.type,
          body: Readable.from(fileBuffer),
        },
        fields: "id",
      });

      const newFileId = uploadResult.data.id;

      if (newFileId) {
        await driveApi.permissions.create({
          fileId: newFileId,
          requestBody: {
            role: "reader",
            type: "anyone",
          },
        });

        photoUrl = `https://drive.google.com/uc?export=view&id=${newFileId}`;
      }
    }

    await sheetsApi.spreadsheets.values.append({
      spreadsheetId: SPREADSHEET_ID,
      range: "Sheet1!A:D",
      valueInputOption: "USER_ENTERED",
      requestBody: {
        values: [[username, userEmail, userMessage, photoUrl]],
      },
    });

    return NextResponse.json({ success: true }, { status: 200 });
  } catch (err) {
    console.error("Upload error:", err);
    return NextResponse.json({ error: "Upload failed" }, { status: 500 });
  }
}

Frontend Display Code

"use client";
import { Box, Image, Stack } from "@mantine/core";
import { useEffect, useState } from "react";

interface DataEntry {
  username: string;
  userEmail: string;
  userMessage: string;
  photoId: string;
  photoUrl: string | null;
}

export default function DisplayPage() {
  const [entries, setEntries] = useState<DataEntry[]>([]);

  useEffect(() => {
    const loadData = async () => {
      const response = await fetch("/api/fetch-data");
      const result = await response.json();
      setEntries(result);
    };
    loadData();
  }, []);

  return (
    <Stack>
      {entries.map((entry, index) => (
        <Box key={index}>
          <Image
            width={250}
            height={250}
            src={entry.photoUrl}
            alt="User upload"
          />
        </Box>
      ))}
    </Stack>
  );
}

I’ve been struggling with this for multiple days now. The uploads succeed, yet showing these images causes my application to crash. Any suggestions on what could be the issue?

what error messages show up in the browser console when it crashes? does this happen with all image types or just specific formats? try adding error handling to your Image component to see what’s actually failing.

The crash is probably Google Drive’s authentication getting in the way. Even though your backend sets public permissions, the frontend still hits CORS issues or auth problems when trying to access Drive URLs directly. I had the same issue and fixed it by creating a proxy endpoint in my backend. It grabs the image data from Google Drive and serves it to the frontend, which bypasses all the browser security headaches. You could also try Google Drive’s thumbnail API or just switch to something more frontend-friendly like Cloudinary or AWS S3. They’re way more reliable for direct web access without all the auth complexity that Drive throws at browser requests.

Check your console for specific error messages first. The Mantine Image component might be causing the crashes - try switching to a regular HTML img tag to test. Also, that Drive URL format can be unreliable. Try https://lh3.googleusercontent.com/d/${fileId} instead.