File tree Expand file tree Collapse file tree 4 files changed +100
-11
lines changed
Expand file tree Collapse file tree 4 files changed +100
-11
lines changed Original file line number Diff line number Diff line change 1+ import getConfig from "next/config" ;
2+ import Image from "next/image" ;
3+ import { useState , useEffect } from "react" ;
4+
5+ const IMAGE_PLACEHOLDER = "/images/landscape-placeholder.svg" ;
6+
7+ export default function ImageSafe ( { src, alt } : { src : string ; alt : string } ) {
8+ const [ imageSrc , setImageSrc ] = useState < string | null > ( null ) ;
9+
10+ useEffect ( ( ) => {
11+ const checkImageConfig = async ( ) => {
12+ try {
13+ const res = await fetch (
14+ "/api/check-image?url=" + encodeURIComponent ( src )
15+ ) ;
16+ console . log ( res ) ;
17+ if ( res . ok ) {
18+ setImageSrc ( src ) ;
19+ } else {
20+ console . error ( "Image source not configured in next.config.js" ) ;
21+ console . log ( res ) ;
22+ setImageSrc ( IMAGE_PLACEHOLDER ) ;
23+ }
24+ } catch ( error ) {
25+ console . error ( "Error checking image configuration:" , error ) ;
26+ setImageSrc ( IMAGE_PLACEHOLDER ) ;
27+ }
28+ } ;
29+
30+ checkImageConfig ( ) ;
31+ } , [ src ] ) ;
32+
33+ if ( ! imageSrc ) {
34+ return null ; // 또는 로딩 표시기
35+ }
36+
37+ return (
38+ < Image
39+ fill
40+ src = { imageSrc }
41+ alt = { alt }
42+ style = { {
43+ objectFit : "cover" ,
44+ } }
45+ />
46+ ) ;
47+ }
Original file line number Diff line number Diff line change 11import { Article , ArticleList } from "@/types/Article.type" ;
22import Image from "next/image" ;
33import styles from "./PostBoard.module.css" ;
4- import { useEffect , useRef , useState } from "react" ;
4+ import { Suspense , useEffect , useRef , useState } from "react" ;
55import {
66 getArticleList ,
77 GetArticleListParams ,
88 OrderBy ,
99} from "@/api/article.api" ;
1010import formatDate from "../lib/formatDate" ;
1111import { useDeviceType } from "@/contexts/DeviceTypeContext" ;
12+ import ImageSafe from "./ImageSafe" ;
1213
1314const DEFAULT_PARAMS : GetArticleListParams = {
1415 page : 1 ,
@@ -143,22 +144,13 @@ export default function PostBoard({
143144
144145function PostItem ( { article } : { article : Article } ) {
145146 const createdAt = formatDate ( article . createdAt ) ;
146- const [ imgSrc , setImgSrc ] = useState ( article . image || IMAGE_PLACEHOLDER ) ;
147147
148148 return (
149149 < div className = { styles . Item } >
150150 < div className = { styles . ItemContent } >
151151 < h3 className = { styles . ItemTitle } > { article . title } </ h3 >
152152 < div className = { styles . ItemPreview } >
153- < Image
154- fill
155- src = { imgSrc }
156- alt = { article . title }
157- style = { {
158- objectFit : "cover" ,
159- } }
160- onError = { ( ) => setImgSrc ( IMAGE_PLACEHOLDER ) }
161- />
153+ < ImageSafe src = { article . image } alt = { article . title } />
162154 </ div >
163155 </ div >
164156 < div className = { styles . ItemInfo } >
Original file line number Diff line number Diff line change @@ -11,6 +11,18 @@ const nextConfig = {
1111 } ,
1212 ] ,
1313 } ,
14+ publicRuntimeConfig : {
15+ images : {
16+ remotePatterns : [
17+ {
18+ protocol : "https" ,
19+ hostname : "sprint-fe-project.s3.ap-northeast-2.amazonaws.com" ,
20+ port : "" ,
21+ pathname : "/**" ,
22+ } ,
23+ ] ,
24+ } ,
25+ } ,
1426} ;
1527
1628module . exports = nextConfig ;
Original file line number Diff line number Diff line change 1+ import getConfig from "next/config" ;
2+
3+ export default async function handler ( req , res ) {
4+ const { url } = req . query ;
5+ const {
6+ publicRuntimeConfig : {
7+ images : { remotePatterns } ,
8+ } ,
9+ } = getConfig ( ) ;
10+
11+ try {
12+ const imageRes = await fetch ( url ) ;
13+
14+ if ( imageRes . status === 200 ) {
15+ const isValid = remotePatterns . some ( ( pattern ) => {
16+ const srcUrl = new URL ( url ) ;
17+ const validProtocol = srcUrl . protocol . slice ( 0 , - 1 ) === pattern . protocol ;
18+ const validHost = srcUrl . hostname === pattern . hostname ;
19+ return validProtocol && validHost ;
20+ } ) ;
21+
22+ if ( isValid ) {
23+ res . status ( 200 ) . json ( { imgSrc : url } ) ;
24+ } else {
25+ res . status ( 403 ) . json ( {
26+ message : "Image source not configured in next.config.js" ,
27+ } ) ;
28+ }
29+ } else {
30+ res . status ( 400 ) . json ( {
31+ message : "URL does not point to a valid image" ,
32+ } ) ;
33+ }
34+ } catch ( error ) {
35+ console . error ( "Error checking image:" , error ) ;
36+ res . status ( 500 ) . json ( { imessage : "Error checking image" } ) ;
37+ }
38+ }
You can’t perform that action at this time.
0 commit comments