diff --git a/config/base.next.config.js b/config/base.next.config.js
index 3c76e311..0f0a3239 100644
--- a/config/base.next.config.js
+++ b/config/base.next.config.js
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-var-requires */
-const IS_PROD = process.env.NODE_ENV === "production";
+const isProd = process.env.NODE_ENV === "production";
+const cloudName = process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME || "";
// The folders containing files importing twin.macro
const path = require("path");
@@ -62,16 +63,10 @@ module.exports = () => ({
return config;
},
images: {
- unoptimized: true,
- remotePatterns: [
- {
- protocol: "https",
- hostname: "**",
- },
- ],
+ unoptimized: !isProd || !cloudName,
// Link: https://fe-developers.kakaoent.com/2022/220714-next-image/
- imageSizes: [64, 256],
- deviceSizes: [512],
+ deviceSizes: [440],
+ imageSizes: [100, 200],
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
},
sentry: {
@@ -81,6 +76,6 @@ module.exports = () => ({
// https://webpack.js.org/configuration/devtool/ and
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-hidden-source-map
// for more information.
- hideSourceMaps: IS_PROD,
+ hideSourceMaps: isProd,
},
});
diff --git a/config/cloudinary-loader.ts b/config/cloudinary-loader.ts
new file mode 100644
index 00000000..99dfbb06
--- /dev/null
+++ b/config/cloudinary-loader.ts
@@ -0,0 +1,26 @@
+"use client";
+
+import type { ImageLoaderProps } from "next/image";
+
+const cloudName = process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME || "";
+
+export function cloudinaryLoader({ src, width, quality }: ImageLoaderProps) {
+ const rawTransformations = ["f_auto", "c_limit", `w_${width}`, `q_${quality || "auto"}`];
+ let isAbsolute: boolean;
+ let href: string;
+
+ if (src.startsWith("/")) {
+ href = src;
+ isAbsolute = false;
+ } else {
+ const hrefParsed = new URL(src);
+ href = hrefParsed.toString();
+ isAbsolute = true;
+ }
+
+ const cldUrl = `https://res.cloudinary.com/${cloudName}/image/fetch/${rawTransformations.join(
+ ",",
+ )}/${href}`;
+
+ return isAbsolute ? cldUrl : src;
+}
diff --git a/src/common/components/Navigation/SideBar/LoginSideBarContent.tsx b/src/common/components/Navigation/SideBar/LoginSideBarContent.tsx
index a4a5a2eb..fb303639 100644
--- a/src/common/components/Navigation/SideBar/LoginSideBarContent.tsx
+++ b/src/common/components/Navigation/SideBar/LoginSideBarContent.tsx
@@ -1,3 +1,4 @@
+import { cloudinaryLoader } from "config/cloudinary-loader";
import Link from "next/link";
import { Icon } from "@/common/components/Icon";
@@ -17,7 +18,13 @@ export const LoginSideBarContent = (props: LoginSideBarContentProps) => {
<>
-
+
{user?.name}
diff --git a/src/common/components/Navigation/SideBar/LogoutSideBarContent.tsx b/src/common/components/Navigation/SideBar/LogoutSideBarContent.tsx
index ca246dce..973d782a 100644
--- a/src/common/components/Navigation/SideBar/LogoutSideBarContent.tsx
+++ b/src/common/components/Navigation/SideBar/LogoutSideBarContent.tsx
@@ -15,7 +15,13 @@ export const LogoutSideBarContent = (props: LogoutSideBarContentProps) => {
<>
);
diff --git a/src/common/components/RandomImge/RandomImage.tsx b/src/common/components/RandomImge/RandomImage.tsx
index acef46bc..c10bbea7 100644
--- a/src/common/components/RandomImge/RandomImage.tsx
+++ b/src/common/components/RandomImge/RandomImage.tsx
@@ -2,7 +2,7 @@ import type { ComponentProps } from "react";
import { Photo } from "../Photo";
-interface Props extends ComponentProps {
+interface Props extends Omit, "alt" | "src" | "sizes"> {
images?: { name: string; src: string }[];
}
const randomImages = [
@@ -33,5 +33,13 @@ const randomImages = [
];
export const RandomImage = ({ images = randomImages, className = "" }: Props) => {
const randomImage = images[Math.floor(Math.random() * images.length)];
- return ;
+ return (
+
+ );
};
diff --git a/src/features/common/components/InfiniteMemeList.tsx b/src/features/common/components/InfiniteMemeList.tsx
index 5462bc28..d2e80916 100644
--- a/src/features/common/components/InfiniteMemeList.tsx
+++ b/src/features/common/components/InfiniteMemeList.tsx
@@ -4,7 +4,7 @@ import { MemeItem } from "@/features/common";
import type { Meme } from "@/types";
interface InfiniteMemeListProps {
- memeList: Meme[];
+ memeList: (Meme & { priority?: boolean })[];
onRequestAppend: () => void;
}
diff --git a/src/features/common/components/MemeItem.tsx b/src/features/common/components/MemeItem.tsx
index bcbb5997..339590de 100644
--- a/src/features/common/components/MemeItem.tsx
+++ b/src/features/common/components/MemeItem.tsx
@@ -1,3 +1,4 @@
+import { cloudinaryLoader } from "config/cloudinary-loader";
import { memo } from "react";
import { Icon } from "@/common/components/Icon";
@@ -8,7 +9,7 @@ import { MemeActionSheet, useMoveMemeDetail } from "@/features/common";
import type { Meme } from "@/types";
interface Props {
- meme: Meme;
+ meme: Meme & { priority?: boolean };
onClick?: (id: number) => void;
}
@@ -32,7 +33,8 @@ export const MemeItem = memo(({ meme, onClick }: Props) => {
className="rounded-16"
draggable={false}
height={image.images[0]?.imageHeight}
- sizes="100px"
+ loader={cloudinaryLoader}
+ sizes="200px"
src={image.images[0]?.imageUrl}
unoptimized={isEncodingError(image.images[0]?.imageUrl)}
width={image.images[0]?.imageWidth}
diff --git a/src/features/common/components/TagCategory/CategoryContent.tsx b/src/features/common/components/TagCategory/CategoryContent.tsx
index 6a9cb8ca..9a0dde39 100644
--- a/src/features/common/components/TagCategory/CategoryContent.tsx
+++ b/src/features/common/components/TagCategory/CategoryContent.tsx
@@ -64,7 +64,13 @@ export const CategoryContent = () => {
gtmTrigger[category.name]
} flex w-full items-center justify-between gap-8 rounded-full px-4 py-12 text-16-semibold-140 [&>span>#chevronDown]:data-[state=open]:rotate-180`}
>
-
+
{category.mainTags.length ? (
{
-
-
+
{FAVORITE_ID}
{
}
return (
<>
-
+
fetchNextPage({ cancelRefetch: false })}
@@ -29,9 +34,10 @@ export const MemesByTagsContainer = ({ tag }: Props) => {
interface ThumbnailProps {
image: string;
+ tag: string;
totalCount: number;
}
-const Thumbnail = React.memo(function Thumbnail({ image, totalCount }: ThumbnailProps) {
+const Thumbnail = React.memo(function Thumbnail({ image, tag, totalCount }: ThumbnailProps) {
const router = useRouter();
const clipboard = useClipboard();
const toast = useToast();
@@ -40,7 +46,14 @@ const Thumbnail = React.memo(function Thumbnail({ image, totalCount }: Thumbnail
return (
-
+
{totalCount}개 밈