-
Notifications
You must be signed in to change notification settings - Fork 743
fix: remove hardcoded R2 public URL and use env variable instead #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@vedantterse is attempting to deploy a commit to the Goshen Labs Team on Vercel. A member of the Team first needs to authorize it. |
PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
WalkthroughThe changes remove hardcoded Cloudflare R2 public URLs by introducing an Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes The changes follow a consistent, homogeneous pattern: replacing hardcoded URLs with environment variables across three configuration/integration points. Logic is straightforward with minimal complexity. Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
PR Code Suggestions ✨Explore these optional code suggestions:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
.env.example (1)
12-12
: Document the expected format for R2_PUBLIC_URL.The environment variable lacks documentation about its expected format. Users need to know whether to include the protocol (https://) and whether a trailing slash should be present.
Apply this diff to add helpful documentation:
# Cloudflare R2 R2_UPLOAD_IMAGE_ACCESS_KEY_ID= R2_UPLOAD_IMAGE_SECRET_ACCESS_KEY= CLOUDFLARE_ACCOUNT_ID= R2_UPLOAD_IMAGE_BUCKET_NAME=images -R2_PUBLIC_URL= +# R2 bucket public URL (include protocol, no trailing slash) +# Example: https://pub-xxxxxx.r2.dev +R2_PUBLIC_URL=Note: The static analysis tool suggests reordering this key to appear before
R2_UPLOAD_IMAGE_ACCESS_KEY_ID
for alphabetical consistency, but this is optional.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
.env.example
(1 hunks)lib/upload-image.ts
(1 hunks)next.config.ts
(1 hunks)
🧰 Additional context used
🪛 dotenv-linter (4.0.0)
.env.example
[warning] 12-12: [UnorderedKey] The R2_PUBLIC_URL key should go before the R2_UPLOAD_IMAGE_ACCESS_KEY_ID key
(UnorderedKey)
); | ||
|
||
const publicUrl = `https://pub-6f0cf05705c7412b93a792350f3b3aa5.r2.dev/${key}`; | ||
const publicUrl = `${process.env.R2_PUBLIC_URL}/${key}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add validation and normalization for R2_PUBLIC_URL.
The code doesn't validate that R2_PUBLIC_URL
is defined, which will result in URLs like "undefined/image.png"
if the environment variable is missing. Additionally, if the URL has a trailing slash, the result will be malformed (e.g., "https://example.com//key"
).
Apply this diff to add validation and handle trailing slashes:
- const publicUrl = `${process.env.R2_PUBLIC_URL}/${key}`;
+ const baseUrl = process.env.R2_PUBLIC_URL;
+ if (!baseUrl) {
+ throw new Error("R2_PUBLIC_URL environment variable is not configured");
+ }
+ const normalizedBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
+ const publicUrl = `${normalizedBase}/${key}`;
return publicUrl;
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const publicUrl = `${process.env.R2_PUBLIC_URL}/${key}`; | |
const baseUrl = process.env.R2_PUBLIC_URL; | |
if (!baseUrl) { | |
throw new Error("R2_PUBLIC_URL environment variable is not configured"); | |
} | |
const normalizedBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; | |
const publicUrl = `${normalizedBase}/${key}`; | |
return publicUrl; |
🤖 Prompt for AI Agents
In lib/upload-image.ts around line 26, the code builds publicUrl directly from
process.env.R2_PUBLIC_URL which may be undefined or contain a trailing slash;
update the code to first validate that process.env.R2_PUBLIC_URL is defined
(throw a clear error or return a failure if not), then normalize the value by
trimming whitespace and removing any trailing slash (or use the URL/URL
constructor to resolve paths) before concatenating the key so you never produce
"undefined/..." or double slashes; ensure the final join guarantees exactly one
slash between base URL and key.
{ | ||
protocol: "https", | ||
hostname: "pub-6f0cf05705c7412b93a792350f3b3aa5.r2.dev", | ||
hostname: process.env.R2_PUBLIC_URL?.replace(/^https?:\/\//, "") || "", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve hostname extraction and handle missing R2_PUBLIC_URL.
The current implementation has several issues:
- The empty string fallback will create an invalid
remotePatterns
entry whenR2_PUBLIC_URL
is not set, potentially causing Next.js configuration errors. - The regex approach doesn't handle URLs with path segments (e.g.,
https://example.com/bucket
→ invalid hostnameexample.com/bucket
). - If the URL lacks a protocol, the regex has no effect, which could lead to an invalid hostname.
Apply this diff to properly parse the hostname using the URL API:
+const getR2Hostname = () => {
+ const url = process.env.R2_PUBLIC_URL;
+ if (!url) {
+ console.warn("R2_PUBLIC_URL is not configured. R2 image optimization will not work.");
+ return undefined;
+ }
+ try {
+ // Ensure URL has protocol for parsing
+ const fullUrl = url.startsWith('http') ? url : `https://${url}`;
+ return new URL(fullUrl).hostname;
+ } catch (error) {
+ console.error("Invalid R2_PUBLIC_URL format:", url);
+ return undefined;
+ }
+};
+
const nextConfig: NextConfig = {
/* config options here */
reactStrictMode: false,
typescript: {
ignoreBuildErrors: true,
},
images: {
- remotePatterns: [
+ remotePatterns: [
+ ...(getR2Hostname() ? [{
- {
protocol: "https",
- hostname: process.env.R2_PUBLIC_URL?.replace(/^https?:\/\//, "") || "",
- },
+ hostname: getR2Hostname()!,
+ }] : []),
{
protocol: "https",
hostname: "jdj14ctwppwprnqu.public.blob.vercel-storage.com",
This approach:
- Uses the URL API for robust hostname extraction
- Handles missing protocol gracefully
- Excludes the pattern entirely if R2_PUBLIC_URL is not configured (rather than using an empty string)
- Provides helpful warnings in the console
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In next.config.ts around line 13, the hostname extraction from R2_PUBLIC_URL is
brittle and can produce invalid remotePatterns entries; update the code to:
check if process.env.R2_PUBLIC_URL is set, if not omit the R2_REMOTE pattern
entirely and emit a console.warn; if set, ensure the value has a protocol
(prepend "https://" if missing), parse it with the URL constructor to extract
only the hostname (no path or port), and use that hostname in remotePatterns so
Next.js never receives an empty or path-containing host; also catch and warn on
URL parsing errors and fall back to omitting the pattern.
User description
Fixes #57
Replaced hardcoded Cloudflare R2 public URL with an environment variable to allow custom bucket configurations.
Changes made:
This makes the setup compatible with any Cloudflare R2 bucket and avoids upload errors for users using their own configuration.
PR Type
Bug fix, Enhancement
Description
Replaced hardcoded Cloudflare R2 public URL with environment variable
Updated image upload logic to use dynamic R2_PUBLIC_URL configuration
Modified Next.js config to extract hostname from environment variable
Added R2_PUBLIC_URL to .env.example for user configuration
Diagram Walkthrough
File Walkthrough
upload-image.ts
Use environment variable for R2 public URL
lib/upload-image.ts
process.env.R2_PUBLIC_URL
environment variable
next.config.ts
Configure Next.js image hostname dynamically
next.config.ts
process.env.R2_PUBLIC_URL
.env.example
Document R2_PUBLIC_URL environment variable
.env.example
R2_PUBLIC_URL
environment variable to example configurationSummary by CodeRabbit