Skip to content

Commit

Permalink
fix(image fetching): add proxy endpoint
Browse files Browse the repository at this point in the history
to allow fetching from google drive and getting rid of the image hostnames env variable
  • Loading branch information
ythepaut committed Sep 16, 2024
1 parent a21e2f1 commit e795f57
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 20 deletions.
2 changes: 0 additions & 2 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@ IMAGES_URL=http://showcase.ythepaut.com/assets/images.json

TIMEZONE=Europe/Paris
DEFAULT_LOCALE=fr

IMAGE_HOSTNAME_PATTERNS=*.ythepaut.com
2 changes: 0 additions & 2 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,3 @@ IMAGES_URL=http://localhost:3000/assets/images_test.json

TIMEZONE=Europe/Paris
DEFAULT_LOCALE=fr

IMAGE_HOSTNAME_PATTERNS=placehold.co
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
Choose one of the following methods:

a. Vercel deployment\
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/ythepauts-projects/clone?repository-url=https%3A%2F%2Fgithub.com%2Fythepaut%2Fshowcase&env=ENVIRONMENT,APP_NAME,APP_DESCRIPTION,APP_KEYWORDS,APP_URL,IMAGES_URL,TIMEZONE,DEFAULT_LOCALE,IMAGE_HOSTNAME_PATTERNS)
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/ythepauts-projects/clone?repository-url=https%3A%2F%2Fgithub.com%2Fythepaut%2Fshowcase&env=ENVIRONMENT,APP_NAME,APP_DESCRIPTION,APP_KEYWORDS,APP_URL,IMAGES_URL,TIMEZONE,DEFAULT_LOCALE)

b. Manual installation
- Clone this repository
Expand Down Expand Up @@ -62,9 +62,6 @@ Choose one of the following methods:
# Your timezone and default locale (only fr and en are supported)
TIMEZONE=Europe/Paris
DEFAULT_LOCALE=fr

# Comma separated patterns to the image hosts (e.g. cdn.mydomain.com, placehold.co, *.pixabay.com)
IMAGE_HOSTNAME_PATTERNS=
```


Expand Down
9 changes: 1 addition & 8 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,7 @@ const nextConfig = {
timeZone: process.env.TIMEZONE ?? "UTC"
},
reactStrictMode: true,
swcMinify: true,
images: {
remotePatterns: process.env.IMAGE_HOSTNAME_PATTERNS.split(/\s*,\s*/).map(pattern => ({
protocol: "https",
hostname: pattern,
pathname: "/**"
}))
}
swcMinify: true
};

module.exports = withNextIntl(nextConfig);
2 changes: 1 addition & 1 deletion src/components/details/ImageCarousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default function ImageCarousel({ selectedImageId, images }: Readonly<Prop
passHref>
<NextImage
className="object-cover w-full h-full rounded-50"
src={image.src}
src={`/api/image?url=${encodeURIComponent(image.src)}`}
alt={image.title}
width={image.width}
height={image.height}
Expand Down
4 changes: 2 additions & 2 deletions src/components/details/ImageViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export default function ImageViewer({ image }: Readonly<Props>): ReactElement {
});
bp.open({
items: [{
img: image.src,
thumb: image.src,
img: `/api/image?url=${encodeURIComponent(image.src)}`,
thumb: `/api/image?url=${encodeURIComponent(image.src)}`,
width: image.width,
height: image.height,
alt: image.title
Expand Down
2 changes: 1 addition & 1 deletion src/components/gallery/ImageTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default function ImageTile({ image }: Readonly<Props>): ReactElement {
<div className="relative group">
<NextImage
className="w-full rounded-50 cursor-pointer"
src={image.src}
src={`/api/image?url=${encodeURIComponent(image.src)}`}
alt={image.title}
width={image.width}
height={image.height}
Expand Down
25 changes: 25 additions & 0 deletions src/pages/api/image.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { type NextApiRequest, NextApiResponse } from "next";

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { url } = req.query;

if (!url || typeof url !== "string") {
return res.status(400).json({ error: "Invalid URL" });
}

try {
const response = await fetch(url as string, {
method: "GET"
});
const contentType = response.headers.get("content-type") ?? "application/octet-stream";
const buffer = Buffer.from(await response.arrayBuffer());

res.setHeader("Content-Type", contentType);
res.setHeader("Content-Length", buffer.length.toString());

res.status(200).send(buffer);
} catch (error) {
console.warn(`Could not fetch image :\n${error}`);
res.status(500).json({ error: `Failed to fetch image \"${url}\"` });
}
}

0 comments on commit e795f57

Please sign in to comment.