• [NextJS] 링크 정보 숨겨서 query값만 받아오기

    Router as, Link as란?

    실제 URL 정보를 사용자가 보지 못하도록 숨겨주는 기능

     

    Router as

    import Router from 'next/router'
    
    const click = () => {
      Router.push('실제로 이동할 주소', '사용자에게 보여줄 주소')
    }

     

    Link as

    <Link href="실제 이동할 주소" as="사용자에게 보여줄 주소">
      <span>이동</span>
    </Link>

    사용 예시

    현재 작업 중인건 `Link as`로 진행 중인거라

    해당 내용을 알게 되고 쉽게 해결이 가능하구나! 하고 접근했다. 바로 도전!

    <Link href={`/projects/${id}`} as={`projects/${title}`}>

     

    문제

    이렇게 접근하면 당연히 되는거구나 했는데 전혀 그렇지 않다.

    id값을 받아서 ssr에서 사용할려고하는데 as에 담았던 title이 담겨져 오는 것이었다.

    기능이 제대로 구현 안되네! 라고 생각했는데 이유는 간단했다.

    바로 `params`로 id를 가져왔었는데 당연히 현재 url은 title로만 되있기 때문에!!

     

    해결

    <Link href={`/projects/${title}?id=${id}`} as={`projects/${title}`}>

     

    해결은 간단하게 됐다.

    원하는 id값을 href에 query 값으로 담아가는 것!

    export const getServerSideProps: GetServerSideProps = async (ctx: GetServerSidePropsContext) => {
      const { id: pageId } = ctx.query;

     

    가져온 값에서 `query` 값인 id를 추출해서 사용

    `params`값이 필요하다면 따로 뽑아쓸 수도 있다.


    마무리

    이 부분을 해결하기 위해서 검색을 좀 했는데 생각보다 mapping이나 nextconfig를 만지고 복잡하고

    router as로 해야 뭔가 더 용이한 것처럼 나와서 바꿔야하나 고민했었는데

    좀 더 쉬운 해결법을 찾다가 오히려 더 짧은 코드로만 해결되어서 기분이가 좋당

    다른 프로젝트에서도 유용하게 사용할 듯!

  • [NextJS] Notion API - 컬러 맵핑

    notion api에서 block으로 가져온 데이터를 가져오고 보니 block으로 객체형태로 오면서
    type이나 color나 나뉘어서 와서 그걸 보고 색깔도 똑같이 할 수 있겠다 싶어서 따로 utils 파일로 빼서 작업을 해봤다

     

    1. 컬러 매핑 함수

    `color-maaping.ts`

    // 색상 매핑 객체
    const colorMap: { [key: string]: string } = {
      red: 'bg-custom-red dark:bg-custom-red-dark',
      orange: 'bg-custom-orange dark:bg-custom-orange-dark',
      // 원하는 부분 여기에 계속해서 추가
    };
    
    // 클래스 네임 설정 함수
    export const getBgColorClassName = (color: string) => {
      return colorMap[color] || 'bg-custom-default dark:bg-custom-default-dark'; // 기본값 설정 가능
    };

     

    먼저 원하는 컬러명과 사용할 클래스를 적용해놓는다.

     

    2. 컬러 매핑 함수 사용

    `tags.tsx`

    import { getBgColorClassName } from '@/utils/bg-color-mapping';
    import classNames from 'classnames';
    
    interface Props {
      tags: {
        id: string;
        name: string;
        color: string;
      }[];
      wrap: string;
    }
    
    const CommonTags = ({ tags, wrap }: Props) => {
      return (
        <div className={wrap}>
          {tags.map(aTag => (
            <h6
              className={classNames(
                'px-2 py-1 rounded-md w-30',
                getBgColorClassName(aTag.color), // 동적 클래스 설정
              )}
              key={aTag.id}
            >
              {aTag.name}
            </h6>
          ))}
        </div>
      );
    };
    
    export default CommonTags;

     

    클래스를 중복으로 사용할 수 있는 `classnames`를 사용해서 해당 함수를 사용한다.

     

    3. tailwind.config 추가 ( 중요! )

    tailwind에 custom한 함수가 사용할 수 있게끔 선언해야한다

    클래스는 적용이 됐는데 css가 적용이 되지 않아서 여기서 찾는데 꽤 걸렸는데 그 이유는 다음과 같다
    tailwind CSS JIT 모드에서 특정 클래스를 항상 생성하고 싶다면 `safelist`를 사용해야 한다.

    이는 코드에서 해당 클래스가 실제로 사용되지 않더라도 생성되도록 보장하기 때문이다.

    반면에 colors 설정은 색상 팔레트를 정의하지만, 이를 사용한 클래스가 실제로 사용되지 않으면 해당 클래스가 생성되지 않는다.

    따라서, `동적으로 클래스가 사용되는 경우 safelist를 사용하여 필요한 클래스를 보장`하는 것이 중요

     

    `tailwind.config.js`

    /** @type {import('tailwindcss').Config} */
    module.exports = {
      mode: 'jit',
      content: [
        './app/**/*.{js,ts,jsx,tsx,mdx}',
        './pages/**/*.{js,ts,jsx,tsx,mdx}',
        './components/**/*.{js,ts,jsx,tsx,mdx}',
    
        // Or if using `src` directory:
        './src/**/*.{js,ts,jsx,tsx,mdx}',
      ],
      darkMode: 'class',
      theme: {
        extend: {
          colors: {
            'custom-red': 'rgb(255, 226, 221)',
            'custom-red-dark': 'rgb(110, 54, 48)',
            // 여기에 원하는 컬러 추가
          },
        },
      },
      safelist: [
        'bg-custom-red',
        'dark:bg-custom-red-dark',
        // 여기에 원하는 전체 클래스명 추가
      ],
      plugins: [],
    };

     

  • [NextJS] Notion API - 기간 맵핑

    notion api에서 block으로 가져온 데이터를 가져오고 보니 block으로 객체형태로 오면서

    기간이 date로 오면서 해당 부분을 원하는 모양으로 custom하고 싶어서 해당 작업을했다. 

     

    `period-maaping.ts`

    export const calculatedPeriod = (start: string, end: string): string => {
      const startDateStringArray = start.split('-');
      const endDateStringArray = end.split('-');
    
      var startDate = new Date(
        Number(startDateStringArray[0]),
        Number(startDateStringArray[1]) - 1, // 월은 0부터 시작하므로 -1 필요
        Number(startDateStringArray[2]),
      );
      var endDate = new Date(
        Number(endDateStringArray[0]),
        Number(endDateStringArray[1]) - 1, // 월은 0부터 시작하므로 -1 필요
        Number(endDateStringArray[2]),
      );
    
      const diffInMs = Math.abs(endDate.getTime() - startDate.getTime());
      const days = diffInMs / (1000 * 60 * 60 * 24);
      const result = Math.floor(days / 7);
    
      return result === 0 ? `${days}일` : `${result}주`;
    };

     

    3주 걸렸는데 21일이라고 표시되는게 너무 과격해서 '주'로 보여지게끔 작업했다.

    그치만 1주일도 안걸렸을 경우엔 '일'로 표시하게 작업했다.

     

    `period.tsx`

    import { calculatedPeriod } from '@/utils/period-mapping';
    
    interface Props {
      start: string;
      end: string | null;
    }
    
    const CommonPeriod = ({ start, end }: Props) => {
      return (
        <p className="my-1 ">
          {end ? (
            <>
              작업기간 : {start} ~ {end} ({calculatedPeriod(start, end)})
            </>
          ) : (
            <>작업기간 : {start} ~ (진행 중)</>
          )}
        </p>
      );
    };
    
    export default CommonPeriod;

     

    표시하고 싶은 부분에선 위와 같이 작업했다

  • [Portfolio] Notion API를 이용해 NextJS로 포트폴리오 만들기

    예전부터 포트폴리오를 한 번 만들어보자 했었는데, 항상 미루기만 하고 작업하기가 쉽지가 않았다.

    그런데 이번에 nextjs를 공부하면서 nextjs로 만들면 좋겠다란 생각을 했다.

    그치만 역시 문제는 나중에 파일을 추가할 때마다 새로해야하나.. 라는 귀찮음? 이 들었다.

    그러던 와중 좋은 영상을 보게 됐다.

    바로 `notion api`를 통해서 나의 notion에 등록만해도 바로 등록되는 형식이었다!

    딱 내가 원하는 형태!!!


    시작하기

    먼저 참고한 영상 링크는 여기다.

    Next.js 나만의 포트폴리오 사이트 만들기 (개발하는 김에 배포까지) / LottieFiles, Notion Api, TailwindCSS (youtube.com)

     

    앞에서 나오는 설명은 대부분 넥스트JS로 설치 방법이라 모르는 부분은 영상은 참고하면 될 거 같다.

    나 같은 경우 몰랐던 notion api 부분과 해당 부분에서 헷갈렸던 부분을 설명하겠다.


    Notion API 시작하기

    새 글 작성은 한 후에 `/`슬래쉬를 하게 되면 databases가 나온다. 여기서 등록해서 원하는 카테고리들을 선택하면서 이미지를 등록하면 된다.

    그리고 google에 `notion api`를 클릭해서 로그인 후 키값을 받아야한다.

    해당 내용들은 영상에서 쉽게 보면서해결 할 수 있다. 

    밑에 있는 내용들은 영상에 없어서 정리했다


    문제1 나의 notion과 notion developers와 연결

    영상에서 나오는 영상에선 연결하는 부분을 아무리 찾아도 찾을 수가 없었다.

    아무래도 영상이 나온 시점과 지금 notion이 버전이 달라서 연결 부분에서 헤맸는데 이리저리 둘러보며 해결했다.

    ...을 누르면 connections가 있다. 여기서 연결하면 된다.

     

    문제2 image를 가져올 때 문제되는 부분

    nextjs에서 제공하는 `<Image/>` 태그를 쓰는데 영상과 다르게 오류가 좀 더 나는거 같다.

    아마도 이미지 업로드해서 다운받는 경로가 한 두개 더 추가되거나 달라져서 그런거 같다.

    /** @type {import('next').NextConfig} */
    const nextConfig = {
      reactStrictMode: true,
      images: {
        domains: [
          'www.notion.so',
          'images.unsplash.com',
          's3.us-west-2.amazonaws.com',
          'prod-files-secure.s3.us-west-2.amazonaws.com',
        ],
        path: '/_next/image',
        loader: 'default',
      },
    };
    
    module.exports = nextConfig;

     

    문제3 영상에는 없는 database의 상세내용 가져오기 ( notion color mapping )

    영상에서보면 리스트에서 보이는 내용들만 가져와지고 리스트를 등록해서 해당 프로젝트에 대한 설명을 좀 더 상세하게적었는데, 그것도 화면에 뿌려주고 싶었다.

    하지만 영상에는 그 부분에 대한 설명은 없어서 api를 뒤지다가 `block`으로 가져오면 가능하단걸 알았다. 

     

    notion은 글들이 모두 block 개념이라 해당 개념을 이용해서 한줄씩 가져온다.

    그래서 그 줄들의 `type`들도 지정이 되기에 그걸 이용해서 font-size나 color 등도 맞게 변경하는 작업도 추가로 했다.

    해당 부분은 내용이 길어질 수 있기에 내 블로그에 따른 부분으로 빼놓았으니 거기서 확인하면 될거같다.

    [NextJS] Notion API - 컬러 맵핑 — gmrdlsrkswnl (tistory.com)

     

    [NextJS] Notion API - 컬러 맵핑

    notion api에서 block으로 가져온 데이터를 가져오고 보니 block으로 객체형태로 오면서type이나 color나 나뉘어서 와서 그걸 보고 색깔도 똑같이 할 수 있겠다 싶어서 따로 utils 파일로 빼서

    gmrdlsrkswnl.tistory.com

     

     

    문제4 기간이 Date로 오는데 원하는 모양으로 custom

    날짜 받아오는거 자체를 커스텀하고 싶었다. 해당 내용도 따로 링크로 빼두겠다

    [NextJS] Notion API - 기간 맵핑 — gmrdlsrkswnl (tistory.com)

     

    [NextJS] Notion API - 기간 맵핑

    notion api에서 block으로 가져온 데이터를 가져오고 보니 block으로 객체형태로 오면서기간이 date로 오면서 해당 부분을 원하는 모양으로 custom하고 싶어서 해당 작업을했다.  `period-maaping.ts`export con

    gmrdlsrkswnl.tistory.com

     

     

     


    마무리

    원하던 작업을 이제서야 하게 되서 누가 시키지도 않았는데 새벽까지 작업을 하게 됐다.

    확실히 재밌는 작업을 하니 시간가는지 몰랐다. 다음번엔 내소개 부분이나 티스토리 블로그 글을 가져오는 목록을 만들까 한다. 이것도 재밌을거같다.

    무엇보다 기존 프로젝트를 하면서 공통으로 짜놨단 `any type 사용하지 않기` 같은 규칙들과 함께 적용하니 프로젝트의 완성도가 더 올라간거 같아서 재밌게 했다.

    하지만 역시나 새롭게 디자인을 해야하는데 그건 좀 너무 귀찬...

    결과 화면

     

  • [Javascript] for ...in, for ...of의 차이

     

    for...of 는 배열의 반복에서 사용,
    for...in 객체의 반복에서 사용.

     

    for ... of (배열)

    var arr = [1, 2, 3];
    
    for (var item of arr) {
      console.log(item); // 1, 2, 3
    }

     

    for ... in (객체)

    var obj = {
      a: 1,
      b: 2,
      c: 3
    };
    
    for (var item in obj) {
      console.log(item) // a, b, c
    }

     

     

    알고 있던 내용이지만 사용할 때마다 객체였나 배열이였나 헷갈려서 한번 더 개념정리하면서 포스팅

.
.

블로그에서 더 보기