// 유튜브 링크 형식 변환 function formatVideoLink(link: string) { // 정규식 설명: // ^@? - 문자열 시작, @ 기호 포함 가능 (선택적) // (?:https?:\/\/)? - URL의 시작 부분, http:// 또는 https:// (선택적) // (?:www\.)? - www. 부분 (선택적) // (?:youtube\.com\/watch\?v=|youtu\.be\/) - 유튜브 도메인과 경로 패턴 (2가지 형식) // ([a-zA-Z0-9_-]{11}) - 유튜브 비디오 ID (11자리 영숫자, 언더스코어, 하이픈) // (?:[?&]si=[^&]*)? - ?si= 또는 &si= 파라미터와 그 값 (선택적) c..
프론트엔드

const FileSelectButton = () => { const [file, setFile] = useState(null); function handleFileSelectChange(e: React.ChangeEvent) { const file = e.target.files?.[0]; if (file) { setFile(file); } } return ( 최대 10MB 이하 .jpg, .png 첨부가능 );};export const FileSelectButton_Con..
/** * 랜덤 닉네임 생성 유틸리티 * 형용사와 명사를 조합하여 독특한 닉네임을 생성합니다. */// 형용사 목록const adjectives = [ "행복한", "슬픈", "화난", "지친", "활기찬", "조용한", "시끄러운", "따뜻한", "차가운", "부드러운", "강한", "약한", "빠른", "느린", "밝은", "어두운", "현명한", "용감한", "겸손한", "정직한", "친절한", "엄격한", "귀여운", "멋진", "신비로운", "공정한", "냉철한", "신중한", "논리적인", "객관적인", "분석적인", "통찰력있는", "예리한", "진지한", "사려깊은", "정의로운", "합리적인", "균형잡힌", "엄정한"..

들어가며이 글은 아래 사항이 완료되었다는 가정 하에 진행합니다.구글 플레이 계정 생성 및 승인PWA 적용만약 계정이 생성되어있지 않다면 아래 '계정 생성' 섹션 링크를 통해 계정 생성을 완료해주세요. 사전 준비계정 생성https://play.google.com/console/u/0/developers/5424186097989016611/create-new-app Google Play Console로그인 Google Play Console로 이동accounts.google.comTip계정 생성 시 주소 인증이 이루어져야 합니다.이 때, 주소 인증을 위한 첨부파일은 주민등록표 등본이 가장 정확합니다.https://www.gov.kr/mw/AA020InfoCappView.do?CappBizCD=13100000..

배경필자는 AI 연애재판 사이트 개발 중 사용자가 작성한 사례들의 데이터가 구글에서 검색되지않는 것을 확인했다.구글 서치 콘솔을 확인하자 역시나 사용자들의 게시물 URL 경로가 색인되지 않고 있었고 이로 인해 SEO 최적화가 되지않아 구글 검색에 노출되지 않는다고 판단하였다.하지만 사용자가 게시물 데이터를 직접 한땀한땀 사이트맵으로 작성할 수는 없다고 생각했고 각 사례들의 사이트맵을 동적으로 생성하는 과정을 학습하며 위 글을 작성한다. 코드src/app/sitemap.tsimport { MetadataRoute } from "next";import { supabase } from "@/lib/supabaseClient";export default async function sitemap(): Promis..

const CharacterImageWrapper = styled(Box)` position: relative; width: 120px; height: 120px; border-radius: 50%; overflow: hidden; flex-shrink: 0; border: 1px solid ${({ theme }) => theme.palette.primary.main};`; 의 부모 요소(이미지 래퍼)에 꼭 position : relative;를 추가해야한다.

배경프로젝트 개발 후 Vercel 배포 시 아래와 같은 오류가 발생하였다.연결이 비공개로 설정되어 있지 않습니다. 공격자가 love-court-c75aeux9m-dong-kyu-lees-projects.vercel.app에서 사용자의 정보를 도용하려고 시도할 수 있습니다(예: 비밀번호, 메시지, 신용카드 정보). 이 경고에 대해 자세히 알아보기 net::ERR_CERT_COMMON_NAME_INVALID 향상된 보호 모드를 사용 설정하여 Chrome의 가장 강력한 보안을 활용하세요. 원인추측성이지만 필자의 결론은 '국내 보안 정책으로 인한 Vercel 도메인 차단'이었다.즉, 대한민국에서 Vercel 의 기본 배포 도메인을 차단한 것이다. 해결방법해결방법은 간단하다.Vercel 도메인을 차단했다면 도메..

✅ 왜 Metadata 대신 next-seo를 사용해야 할까?Next.js 15에서는 Metadata API를 사용하여 SEO 메타태그를 설정할 수 있지만, next-seo를 사용하는 것이 더 유리한 상황이 많습니다.아래 이유를 보면 언제 Metadata가 좋고, 언제 next-seo를 사용하는 것이 더 나은지 알 수 있습니다.🚀 1. Metadata API의 한계📌 1-1. Metadata는 서버 컴포넌트에서만 사용 가능Metadata는 서버 컴포넌트에서만 동작하며, 클라이언트 컴포넌트에서는 사용할 수 없음즉, 동적인 SEO 업데이트(예: 사용자 인터랙션에 따른 메타태그 변경)가 불가능클라이언트 컴포넌트("use client"가 포함된 컴포넌트)에서는 Metadata를 직접 사용할 수 없음❌ 예제:..