Next JS에서 query params를 구하는 것은 page에서 한다면 쉽게 할 수 있다. 하지만 왜인지는 모르겠지만, layout에서는 그게 불가능 하다. 그래서 미들웨어를 이용하여 query params을 구하는 함수를 만들어서 공유하고자 한다.
크게보면 이런 순서이다.
가장 쉬운 첫 번째는 미들웨어로 req의 url을 받아서 headers에 붙여 보내주는 것이다.
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
export async function middleware(req: NextRequest) {
const requestHeaders = new Headers(req.headers);
requestHeaders.set('x-url', req.url);
return NextResponse.next({
request: {
headers: requestHeaders,
},
});
}
// matcher는 원하는 데로 설정 한다.
export const config = {
matcher: ['/:path*'],
};
나는 함수형 프로그래밍을 지향하기 때문에 다음과 같은 코드를 만들었다.
// url = 'http://localhost:3000/tours/title?ref=100&ref2=200&ref3=300'
const divideQueryByQuestionMark = (url: string) => url.split('?')[1];
const divideEachQueries = (stringQueryParams: string): string[] =>
stringQueryParams.split('&');
const queryParamsResult = (eachQueries: string[]) =>
eachQueries.map(query => {
const queryKey = query.split('=')[0];
const queryValue = query.split('=')[1];
return { [queryKey]: queryValue };
});
// returns [{ ref = '100' },{ ref2 = '200' },{ ref3 = '300' }]
export const getQueryParams = (url: string) => {
const stringQueryParams: string = divideQueryByQuestionMark(url);
const eachQueries = divideEachQueries(stringQueryParams);
const result = queryParamsResult(eachQueries);
return result;
};
//
//
//
interface QueryParams {
[key: string]: string;
}
interface Params {
query: string;
queryParams?: Array<QueryParams>;
fullUrl?: string;
}
export const searchQueryParams = ({ query, queryParams, fullUrl }: Params) => {
if (queryParams) {
const queryKeys = queryParams.map(keyValuePair => {
const keys = Object.keys(keyValuePair); // ['ref']
const values = Object.values(keyValuePair); // ['1']
if (!keys.includes(query)) {
return;
} else {
const targetIndex = keys.findIndex(key => key === query);
const result = values[targetIndex];
return result;
}
});
const excludePossibleUndefined = queryKeys.filter(el => el !== undefined);
return excludePossibleUndefined[0];
} else if (fullUrl) {
const queryParams = getQueryParams(fullUrl);
const result: unknown = searchQueryParams({
queryParams,
query,
});
return result;
} else {
return undefined;
}
};
//를 기준으로 위 부분과 아래 부분으로 나뉘어 지는데, 하다 보니까 아래의 searchQueryParams함수를 사용함을 목적으로 아래는 새로 만들었다. 즉, searchQueryParams()함수에 인자로 원하는 queryParam의 이름을 적고, url을 적으면 그 queryParams의 값을 리턴하는 함수이다.
예를들어 const url = http://localhost:3000/tours/title?ref=100&ref2=200&ref3=300가 있다고 할 때,
searchQueryParams({query: 'ref3', fullUrl: url})
을 적으면 리턴값으로 300이 나오는 개념이다.