Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion components/common/comment/CommentUserInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export default function CommentUserInfo({ className }: { className?: string }) {
</p>
) : (
// TODO: 추후 서버 수정되면 익명회원 ID를 보여주는 문구 추가
<></>
<p>
<span className='text-secondary500 font-bold'>익명의 댑댑이</span>님 의견을 남겨주세요!
</p>
)}
</section>
);
Expand Down
63 changes: 43 additions & 20 deletions components/meta/MetaHead.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,59 @@ import 뎁구리_og from '@public/image/뎁구리/뎁구리_og.png';

import { META, SITE_URL } from '@/constants/metaData';

const MetaHead = ({
title,
description,
url,
keyword,
image,
}: {
export type MetaHeadProps = {
title?: string;
description?: string;
url?: string;
keyword?: string[];
image?: string;
}) => {
};

const toAbsoluteUrl = (src: string) => {
if (/^https?:\/\//.test(src)) {
return src;
}

try {
return new URL(src, SITE_URL).toString();
} catch {
return `${SITE_URL}${src.startsWith('/') ? src : `/${src}`}`;
}
};

const MetaHead = ({ title, description, url, keyword, image }: MetaHeadProps) => {
const metaTitle = title ?? META.MAIN.title;
const metaDescription = description ?? META.MAIN.description;
const metaKeywords = (keyword ?? META.MAIN.keyword).join(',');
const metaUrl = url ?? SITE_URL;
const defaultImage = toAbsoluteUrl(뎁구리_og.src);
const metaImage = image ? toAbsoluteUrl(image) : defaultImage;

return (
<Head>
<title>{title || META.MAIN.title}</title>
<meta name='description' content={description || META.MAIN.description} />
<title>{metaTitle}</title>
<meta name='description' content={metaDescription} />
<meta name='viewport' content='initial-scale=1.0, width=device-width' />
<meta name='keywords' content={keyword?.join(',') || META.MAIN.keyword.join(',')} />
<meta property='og:title' content={title || META.MAIN.title} />
<meta name='keywords' content={metaKeywords} />

{/* Open Graph */}
<meta property='og:title' content={metaTitle} />
<meta property='og:type' content='website' />
{/* TODO: 최종 url은 변경 필요 */}
<meta property='og:url' content={url || SITE_URL} />
<meta property='og:image' content={image || 뎁구리_og.src} />

{/* 트위터용 */}
<meta name='twitter:title' content={title || META.MAIN.title} />
<meta name='twitter:description' content={description || META.MAIN.description} />
<meta name='twitter:image' content={image || 뎁구리_og.src} />
<meta property='og:url' content={metaUrl} />
<meta property='og:description' content={metaDescription} />
<meta property='og:image' content={metaImage} />
<meta property='og:site_name' content='DEVDEVDEV' />

{/* Twitter */}
<meta name='twitter:card' content='summary_large_image' />
<meta name='twitter:title' content={metaTitle} />
<meta name='twitter:description' content={metaDescription} />
<meta name='twitter:image' content={metaImage} />
<meta name='twitter:url' content={metaUrl} />

<link rel='canonical' href={metaUrl} />
</Head>
);
};

export default MetaHead;
41 changes: 29 additions & 12 deletions pages/_app.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ import { QueryClient, QueryClientProvider, HydrationBoundary } from '@tanstack/r
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';

import Layout from '@components/common/layout';
import MetaHead, { type MetaHeadProps } from '@components/meta/MetaHead';

import useSetAxiosConfig from '@/api/useSetAxiosConfig';
import { DAY, HALF_DAY } from '@/constants/TimeConstants';
import { META } from '@/constants/metaData';
import { MediaQueryProvider } from '@/contexts/MediaQueryContext';
import '@/styles/globals.css';

import * as gtag from '../lib/gtag';

type ComponentWithMeta = AppProps['Component'] & { meta?: MetaHeadProps };

export default function MyApp({ Component, pageProps }: AppProps) {
useSetAxiosConfig();
console.log('process.env.NODE_ENV', process.env.NODE_ENV);
Expand Down Expand Up @@ -54,18 +58,31 @@ export default function MyApp({ Component, pageProps }: AppProps) {
};
}, [router.events]);

const componentMeta = (Component as ComponentWithMeta)?.meta;
const meta: MetaHeadProps =
(pageProps.meta as MetaHeadProps | undefined) ?? componentMeta ?? META.MAIN;

return (
<QueryClientProvider client={queryClient}>
<HydrationBoundary state={pageProps.dehydratedState}>
<ThemeProvider enableSystem={false} attribute='class'>
<MediaQueryProvider>
<Layout>
<Component {...pageProps} />
</Layout>
</MediaQueryProvider>
</ThemeProvider>
</HydrationBoundary>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
<>
<MetaHead
title={meta.title}
description={meta.description}
keyword={meta.keyword}
url={meta.url}
image={meta.image}
/>
<QueryClientProvider client={queryClient}>
<HydrationBoundary state={pageProps.dehydratedState}>
<ThemeProvider enableSystem={false} attribute='class'>
<MediaQueryProvider>
<Layout>
<Component {...pageProps} />
</Layout>
</MediaQueryProvider>
</ThemeProvider>
</HydrationBoundary>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</>
);
}
107 changes: 56 additions & 51 deletions pages/main/index.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import DevGuriError from '@components/common/error/DevGuriError';
import ArrowWithTitle from '@components/common/title/ArrowWithTitle';
import MainTechBlogSection from '@components/features/main/MainTechBlogSection';
import MainCardComponent from '@components/features/main/mainCard/MainCardComponent';
import MetaHead from '@components/meta/MetaHead';

import DevLogo from '@public/image/devdevdevLogo.svg';

import { META } from '@/constants/metaData';
import { useMediaQueryContext } from '@/contexts/MediaQueryContext';

const DynamicPickComponent = dynamic(
Expand Down Expand Up @@ -39,58 +39,63 @@ export default function Index() {
};

return (
<>
<MetaHead />
<div
className={`w-full h-full ${isMobile ? 'px-[1.6rem] py-[2.4rem]' : 'px-[20.3rem] py-[6.4rem]'} `}
>
<MainPageLogo />
<div
className={`w-full h-full ${isMobile ? 'px-[1.6rem] py-[2.4rem]' : 'px-[20.3rem] py-[6.4rem]'} `}
>
<MainPageLogo />

<div className={`grid ${isMobile ? 'grid-cols-1 gap-[9.6rem]' : 'grid-rows-2'}`}>
<section
className={`${MainSectionStyle.base} ${isMobile ? MainSectionStyle.mobile : MainSectionStyle.desktop}`}
>
<MainCardComponent path={PICK_PATH} />
<div className='relative'>
<ArrowWithTitle
title='따끈따끈! 최신 픽픽픽'
variant='mainTitle'
iconText='바로가기'
routeURL={PICK_PATH}
className='pb-[2.45rem]'
/>
<QueryErrorBoundary
fallbackRender={({ handleRetryClick }) => (
<DevGuriError type='network' handleRetryClick={handleRetryClick} />
)}
>
<DynamicPickComponent />
</QueryErrorBoundary>
</div>
</section>
<div className={`grid ${isMobile ? 'grid-cols-1 gap-[9.6rem]' : 'grid-rows-2'}`}>
<section
className={`${MainSectionStyle.base} ${isMobile ? MainSectionStyle.mobile : MainSectionStyle.desktop}`}
>
<MainCardComponent path={PICK_PATH} />
<div className='relative'>
<ArrowWithTitle
title='따끈따끈! 최신 픽픽픽'
variant='mainTitle'
iconText='바로가기'
routeURL={PICK_PATH}
className='pb-[2.45rem]'
/>
<QueryErrorBoundary
fallbackRender={({ handleRetryClick }) => (
<DevGuriError type='network' handleRetryClick={handleRetryClick} />
)}
>
<DynamicPickComponent />
</QueryErrorBoundary>
</div>
</section>

<section
className={`${MainSectionStyle.base} ${isMobile ? MainSectionStyle.mobile : MainSectionStyle.desktop}`}
>
<MainCardComponent path={TECH_PATH} />
<div className='relative'>
<ArrowWithTitle
title='따끈따끈! 최신 아티클'
variant='mainTitle'
iconText='바로가기'
routeURL={TECH_PATH}
/>
<QueryErrorBoundary
fallbackRender={({ handleRetryClick }) => (
<DevGuriError type='network' handleRetryClick={handleRetryClick} />
)}
>
<MainTechBlogSection />
</QueryErrorBoundary>
</div>
</section>
</div>
<section
className={`${MainSectionStyle.base} ${isMobile ? MainSectionStyle.mobile : MainSectionStyle.desktop}`}
>
<MainCardComponent path={TECH_PATH} />
<div className='relative'>
<ArrowWithTitle
title='따끈따끈! 최신 아티클'
variant='mainTitle'
iconText='바로가기'
routeURL={TECH_PATH}
/>
<QueryErrorBoundary
fallbackRender={({ handleRetryClick }) => (
<DevGuriError type='network' handleRetryClick={handleRetryClick} />
)}
>
<MainTechBlogSection />
</QueryErrorBoundary>
</div>
</section>
</div>
</>
</div>
);
}

export function getStaticProps() {
return {
props: {
meta: META.MAIN,
},
};
}
13 changes: 11 additions & 2 deletions pages/pickpickpick/[id]/index.page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Link from 'next/link';
import type { NextPage } from 'next';
import { useRouter } from 'next/router';

import DevLoadingComponent from '@pages/loading/index.page';
Expand All @@ -16,7 +17,9 @@ import {
PICK_VOTE_MODIFIED_MODAL,
} from '@components/common/modals/modalConfig/pickVote';
import MoreButton from '@components/common/moreButton';
import type { MetaHeadProps } from '@components/meta/MetaHead';

import { META } from '@/constants/metaData';
import { ROUTES } from '@/constants/routes';
import { useMediaQueryContext } from '@/contexts/MediaQueryContext';

Expand All @@ -27,7 +30,9 @@ import SimilarPick from './components/SimilarPick';
import VoteCard from './components/VoteCard';
import usePickDetailHandlers from './handlers/usePickDetailHandlers';

export default function Index() {
type NextPageWithMeta = NextPage & { meta?: MetaHeadProps };

const PickDetailPage: NextPageWithMeta = () => {
const router = useRouter();
const { id } = router.query;

Expand Down Expand Up @@ -148,4 +153,8 @@ export default function Index() {
</div>
</>
);
}
};

PickDetailPage.meta = META.PICK;

export default PickDetailPage;
Loading