💡 채용 페이지를 쉽게 구성하고, 관리할 수 있도록 어드민 페이지를 제공하고, 채용 페이지의 SEO 최적화를 통해 더 많은 구직자들에게 접근할 수 있도록 한다.
Context API를 사용하여 복잡한 폼을 관리하고, 컴포넌트 구조화를 통해 효율적인 상태 관리를 구현했습니다.
- /settings
- /sites
- SettingSiteFormProvider.tsx (Context Provider)
- useSettingSiteFormContext.ts (useContext 커스텀 훅)
- index.tsx (페이지 컴포넌트)
// SettingSiteFormProvider.tsx
const SettingSiteFormProvider = ({
children,
defaultValue,
}) => {
const form = useForm({
defaultValue,
});
// ...
return (
<FormProvider {...form}>
{children}
</FormProvider {...form}>
)
};
// useSettingSiteFormContext.ts
const useSettingSiteFormContext = () => {
const form = useFormContext();
return form;
};
// 활용
// index.tsx
const SettingsSitePage = () => {
// ...
return (
<SettingSiteFormProvider>
<SEOFieldset />
<SocialChannelsFieldset />
</SettingSiteFormProvider>
);
};
// SEOFieldset.tsx
const SEOFieldset = () => {
const form = useSettingSiteFormContext();
// ...
};
IntersectionObserver API를 활용하여 scrollSpy 기능을 구현해, 사용자가 스크롤할 때 현재 위치를 쉽게 파악할 수 있도록 했습니다.
// useScrollSpy.ts
const useScrollSpy = (
targetElements,
options,
) => {
const [activeSection, setActiveSection] = useState('');
useEffect(() => {
const callback = (entries) => {
// ...
};
const observer = new IntersectionObserver(callback, options);
targetElements.forEach((element) => observer.observe(element));
return () => observer.disconnect();
}, [targetElemtns, options]);
return activeSection;
};
서버사이드 렌더링을 통해 동적으로 sitemap.xml을 생성하였습니다.
// sitemap.xml.tsx
const SitemapPage = () => {
return null;
}
export const getServerSideProps = async (context) => {
// ...
const sitemap = generateSiteMap({
siteUrl,
changeFreq,
priority,
});
context.res.setHeader('Content-Type', 'text/xml');
context.res.write(sitemap);
context.res.end();
return { props: {} };
}