2024년 대학 포탈을 Drupal에서 Next.js로 마이그레이션한 사례

2024년 초, 한 대형 주립대학교가 고등교육에서 점점 더 흔해지고 있는 문제를 가지고 우리를 찾아왔습니다. 그들의 Drupal 7 설치가 수명 종료에 다다랐고, 학생 포탈은 등록 기간 동안 부하로 인해 흔들리고 있었으며, 웹사이트에서 가장 중요한 전환 도구인 프로그램 검색 기능은 검색 결과를 반환하는 데 8초 이상 걸렸습니다. 그들은 활성 학생이 40,000명, 200개 이상의 학위 프로그램이 있었고, Drupal 7 보안 지원이 사실상 종료될 때까지 6개월의 기간이 있었습니다. 압박이 없을 수 없었습니다.

이것은 우리가 전체를 Next.js와 헤드리스 CMS 백엔드로 마이그레이션하고, 페이지 로드 시간을 73% 단축하며, 일정대로 출시한 이야기입니다. 우리가 내린 아키텍처 결정(그리고 거의 실수할 뻔했던 결정들), 실제 마이그레이션 프로세스, 성능 벤치마크, 그리고 대규모 CMS 마이그레이션에 적용되는 교훈들을 공유하겠습니다.

목차

사례 연구: Drupal에서 Next.js로 대학 포탈 마이그레이션

시작점: 우리가 다루고 있던 것

상황을 그려보겠습니다. 대학교의 디지털 존재는 Drupal 7 위에 구축되었으며, 원래 2014년경에 출시되었습니다. 지난 10년 동안 다음과 같이 축적되었습니다:

  • 프로그램, 과정, 교수진 프로필, 뉴스 기사, 이벤트 전반에 걸친 ~12,000개의 콘텐츠 노드
  • 200개 이상의 학위 프로그램 페이지 각각 복잡한 분류 관계 포함 (학위 수준, 학부, 단과대, 전달 형식, 인정 상태)
  • 커스텀 프로그램 검색 Drupal Views 기반 검색으로 필터 노출 — 기능하지만 느림
  • 인증된 접근권이 있는 학생 포탈 상담 도구, 학위 감시, 등록 링크, 개인화된 대시보드에 접근
  • 47개의 커스텀 Drupal 모듈, 이 중 19개는 더 이상 유지되지 않음
  • 연속 리디자인에서 쌓인 3개의 다른 테마 레이어

이 사이트는 기관 로드 밸런서 뒤에 있는 두 대의 낡은 가상 머신에서 호스팅되었습니다. 등록 시즌(8월과 1월)이 되면 프로그램 검색은 정기적으로 타임아웃되었습니다. 마케팅 팀은 프로그램의 PDF 목록을 백업으로 게시하는 것으로 귀결되었습니다. 그것이 모든 것을 말해줍니다.

Core Web Vitals은 좋지 않았습니다:

지표 Drupal 7 (이전) 목표
LCP 6.2s < 2.5s
FID 380ms < 100ms
CLS 0.31 < 0.1
TTFB 2.8s < 0.8s
프로그램 검색 로드 8.4s < 1.5s

이해관계자 풍경

대학교 웹 프로젝트는 이해관계자의 수 때문에 유독 까다롭습니다. 우리는 다음과 함께 일하고 있었습니다:

  • 중앙 IT — SSO 통합, 보안 규정 준수, 호스팅 담당
  • 마케팅 및 커뮤니케이션 — 브랜드, 콘텐츠 전략, 분석 소유
  • 등록처 사무소 — 프로그램 데이터 및 학생정보시스템(SIS) 소유
  • 개별 단과대 및 학부 — 각각의 콘텐츠 편집자 (CMS 접근권을 가진 80명 이상)
  • 학생회 — 모바일 우선 디자인을 강력하게 옹호 (당연히 맞음)

이 모든 그룹으로부터 동의를 얻는 데 프로젝트의 처음 3주가 걸렸습니다. 공유 우선순위와 필수 불가결한 요소를 확립하기 위해 디자인 스프린트를 실행했습니다.

Next.js를 선택한 이유 (그리고 Drupal 10을 선택하지 않은 이유)

명백한 질문: Drupal 10으로 업그레이드하지 않는 이유는 무엇입니까? 대학교의 IT 팀은 우리에게 연락하기 6개월 전에 실제로 그 경로를 시작했습니다. 47개 커스텀 모듈 중 23개가 Drupal 10 동등물이 없으며 완전히 다시 작성해야 한다는 것을 발견한 후 포기했습니다.

실제 계산은 다음과 같았습니다:

요소 Drupal 10 마이그레이션 Next.js 재구축
예상 타임라인 8-10개월 6개월
커스텀 모듈 재작성 23개 모듈 N/A (API/컴포넌트로 재구축)
콘텐츠 편집자 재교육 적당함 (새 관리 UI) 적당함 (새 CMS)
성능 천장 적당한 개선 극적인 개선
호스팅 유연성 전통적인 LAMP/유사 Edge 배포, CDN 우선
개발자 채용 풀 축소 (Drupal 전문가) 성장 (React/Next.js)
장기 유지보수 비용 ~$180K/년 ~$95K/년

유지보수 비용 차이가 행정부의 결정권자였습니다. 기관 경험이 있는 Drupal 개발자를 찾기가 점점 더 어려워지고 있었고 유지하기 위해 더 비싸지고 있었습니다. 대학교의 자체 IT 팀은 3명의 React 개발자와 시니어 Drupal 개발자가 은퇴한 후 0명의 Drupal 전문가를 가지고 있었습니다.

우리는 구체적으로 Next.js를 선택했습니다 (Gatsby, Remix 또는 Astro가 아니라) 몇 가지 이유로:

  1. 하이브리드 렌더링 — 프로그램 페이지는 정적으로 생성될 수 있지만, 학생 포탈은 인증을 포함한 서버 측 렌더링이 필요했습니다
  2. API 경로 — 별도의 백엔드 서비스 없이 SIS 통합을 위한 미들웨어를 구축할 수 있습니다
  3. 증분 정적 재생성 (ISR) — 프로그램 데이터는 시간별이 아닌 주간으로 변경됩니다. 1시간 재검증 윈도우를 가진 ISR이 완벽했습니다
  4. 대학교의 팀은 React를 알고 있었습니다 — 인수 후 유지보수할 것입니다

유사한 옵션을 검토 중이라면, 우리의 Next.js 개발 기능 페이지는 우리가 일반적으로 구축하는 기술 사항을 다룹니다.

아키텍처 결정

헤드리스 CMS 선택

우리는 대학교의 요구 사항에 대해 5개의 헤드리스 CMS 옵션을 평가했습니다: 80명 이상의 콘텐츠 편집자, 복잡한 콘텐츠 관계, 역할 기반 권한, 합리적인 좌석당 가격 모델.

우리는 이 프로젝트를 위해 Sanity에 정착했습니다. 주요 요소들:

  • GROQ 쿼리 프로그램, 학부, 단과대 간의 복잡한 분류 관계를 이 사용 사례에서 GraphQL보다 훨씬 잘 다뤘습니다
  • 실시간 협업 — 충돌 없이 여러 편집자가 동시에 작업할 수 있었습니다
  • 커스텀 입력 컴포넌트 — 우리는 Studio에 프로그램 선행 조건 매퍼를 직접 구축했습니다
  • 가격책정 — ~$949/월의 Enterprise 플랜은 예산 범위 내였으며, 사용자별 비용은 예측 가능했습니다

콘텐츠 모델링에는 약 2주가 걸렸습니다. 우리는 14개의 문서 타입과 8개의 참조 타입을 정의했습니다. 프로그램 스키마 자체는 schema.org EducationalOrganizationCourse 마크업을 위한 구조화된 데이터를 포함하여 34개의 필드를 가지고 있었습니다.

CMS 아키텍처에 대한 우리의 접근 방식에 대해 더 알아보려면, 우리의 헤드리스 CMS 개발 페이지를 참조하세요.

인프라

우리는 Next.js 프론트엔드에 대해 Vercel에 배포했습니다 (FERPA 규정 준수 및 SSO 요구사항에 필요한 Enterprise 플랜). 학생 포탈의 인증된 경로는 CAS (Central Authentication Service) SSO를 통한 세션 관리를 사용하여 서버 측 렌더링을 사용합니다.

데이터 흐름은 다음과 같습니다:

[Sanity CMS] → [Next.js on Vercel] → [CDN Edge]
                    ↕
           [University SIS API]
                    ↕
           [CAS SSO / LDAP]

정적 프로그램 페이지는 빌드 시간에 사전 렌더링되고 ISR을 통해 1시간마다 재검증됩니다. 프로그램 검색은 사전 페치된 데이터 (빌드 시간에 클라이언트에 JSON 인덱스로 로드)와 실시간 필터링의 조합을 사용합니다 — 검색 작업에는 서버 왕복이 필요하지 않습니다.

API 레이어

학생정보시스템 (호기심이 있으시다면 Ellucian Banner — 항상 Banner임) SOAP API를 노출했습니다. 네, 2024년에. 우리는 Next.js API 경로를 사용하여 SOAP 엔드포인트를 소비하고 프론트엔드에 깔끔한 REST 엔드포인트를 노출하는 변환 레이어를 구축했습니다:

// /app/api/programs/[programId]/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { fetchFromBanner } from '@/lib/banner-client';
import { transformProgramData } from '@/lib/transforms';

export async function GET(
  request: NextRequest,
  { params }: { params: { programId: string } }
) {
  const bannerData = await fetchFromBanner(
    'PROGRAM_DETAIL',
    { programCode: params.programId }
  );
  
  const program = transformProgramData(bannerData);
  
  return NextResponse.json(program, {
    headers: {
      'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400',
    },
  });
}

이 변환 레이어는 프로젝트의 가장 높은 가치 조각 중 하나였습니다. 그것은 프론트엔드를 Banner의 특이한 점에서 분리했고 대학교에 미래 프로젝트에 사용할 수 있는 깨끗한 API를 제공했습니다 (모바일 앱이 이미 논의 중이었습니다).

사례 연구: Drupal에서 Next.js로 대학 포탈 마이그레이션 - 아키텍처

프로그램 검색: 핵심 기능 재구축

프로그램 검색은 전체 사이트에서 가장 중요한 페이지였습니다. 분석에 따르면 모든 유기 검색 트래픽의 34%를 차지했으며 잠재 학생들의 #1 진입점이었습니다. 이것을 잘못 이해하는 것은 선택지가 아니었습니다.

구식 접근 방식 (그리고 그것이 느린 이유)

Drupal 버전은 노출된 필터와 함께 Views를 사용했습니다. 모든 필터 변경은 전체 서버 왕복을 촉발하고, 데이터베이스를 다시 쿼리하고, 전체 페이지를 다시 렌더링했습니다. 200개 이상의 프로그램과 6개의 분류 치원 (학위 수준, 단과대, 학부, 전달 형식, 관심 영역, 키워드 검색)으로 쿼리는 비용이 많이 들었습니다.

새로운 접근 방식

우리는 빌드 시간에 검색 인덱스를 사전 구축했습니다. 200개 이상의 모든 프로그램은 페이지와 함께 제공되는 ~180KB JSON 파일 (gzip 압축하면 ~22KB)로 직렬화되었습니다. 필터링은 커스텀 훅을 사용하여 전적으로 클라이언트 측에서 발생합니다:

// hooks/useProgramSearch.ts
import { useMemo, useState } from 'react';
import Fuse from 'fuse.js';
import { Program, ProgramFilters } from '@/types';

const fuseOptions = {
  keys: [
    { name: 'title', weight: 0.4 },
    { name: 'description', weight: 0.2 },
    { name: 'keywords', weight: 0.3 },
    { name: 'department', weight: 0.1 },
  ],
  threshold: 0.3,
};

export function useProgramSearch(programs: Program[]) {
  const [filters, setFilters] = useState<ProgramFilters>({});
  const fuse = useMemo(() => new Fuse(programs, fuseOptions), [programs]);

  const results = useMemo(() => {
    let filtered = programs;

    if (filters.degreeLevel) {
      filtered = filtered.filter(p => p.degreeLevel === filters.degreeLevel);
    }
    if (filters.college) {
      filtered = filtered.filter(p => p.college === filters.college);
    }
    if (filters.deliveryFormat) {
      filtered = filtered.filter(p => 
        p.deliveryFormats.includes(filters.deliveryFormat!)
      );
    }
    if (filters.searchQuery) {
      const fuseResults = fuse.search(filters.searchQuery);
      const fuseIds = new Set(fuseResults.map(r => r.item.id));
      filtered = filtered.filter(p => fuseIds.has(p.id));
    }

    return filtered;
  }, [programs, filters, fuse]);

  return { results, filters, setFilters };
}

우리는 퍼지 텍스트 검색에 Fuse.js를 사용했고 패싯에 대해 순수 JavaScript 필터링을 사용했습니다. 결과: 검색 결과는 50ms 미만에 나타납니다. 로딩 스피너 없음. 서버 호출 없음. 사용자는 원하는 만큼 빠르게 필터를 조작할 수 있습니다.

각 프로그램 결과는 전체 schema.org 마크업이 있는 정적으로 생성된 상세 페이지에 연결되어, 대학교가 Google의 교육 관련 검색 기능에서의 표현을 극적으로 개선했습니다.

학생 포탈 마이그레이션

학생 포탈이 가장 까다로운 부분이었습니다. 인증, 개인화, Banner의 실시간 데이터가 필요했습니다. 어느 것도 정적으로 생성할 수 없었습니다.

인증 흐름

대학교는 모든 기관 시스템 전반에 걸쳐 SSO (Single Sign-On)를 위해 CAS를 사용합니다. 우리는 Next.js와 CAS를 커스텀 인증 흐름을 사용하여 통합했습니다:

  1. 인증되지 않은 사용자가 /portal → CAS 로그인으로 리디렉션 → 히트
  2. CAS는 서비스 티켓과 함께 다시 리디렉션
  3. 우리의 API 경로는 CAS 서버에 대한 티켓을 검증합니다
  4. 우리는 httpOnly 쿠키에 저장된 서명된 JWT를 생성합니다
  5. 이후 요청은 세션 관리를 위해 JWT를 사용합니다

우리는 next-auth (이제 Auth.js)를 우리가 처음부터 작성한 커스텀 CAS 공급자와 함께 사용했으며, 당시에 유지된 CAS 공급자가 존재하지 않았기 때문입니다.

포탈 기능

학생 포탈에는 다음이 포함되었습니다:

  • 개인화된 대시보드 다가오는 등록 날짜, 보류 사항, 상담자 정보
  • 학위 감시 요약 Banner에서 실시간으로 당겨옴
  • 빠른 링크 LMS (Canvas), 이메일, 도서관 시스템으로
  • 프로그램별 리소스 학생의 선언된 전공에 따라

모든 포탈 페이지는 서버 측 렌더링을 사용합니다. 우리는 Banner API 응답을 공격적으로 캐시합니다 (대부분의 엔드포인트에는 30초 TTL, 학위 감시에는 5분 TTL) 그들의 시스템에 부하를 주지 않기 위해.

콘텐츠 마이그레이션 전략

12,000개의 콘텐츠 노드를 Drupal에서 Sanity로 마이그레이션하려면 체계적인 접근이 필요했습니다. 우리는 커스텀 마이그레이션 파이프라인을 구축했습니다:

# 간소화된 마이그레이션 파이프라인
1. Drupal 노드 → 커스텀 Drush 명령을 통해 JSON으로 내보내기
2. JSON 변환 → Node.js 스크립트를 통해 Sanity 문서 형식으로
3. 미디어 파일 처리 → Sanity CDN에 업로드
4. 문서 가져오기 → Sanity Migration API
5. 검증 → 손상된 참조에 대한 자동화된 확인

미디어 마이그레이션이 가장 지루한 부분이었습니다. Drupal의 파일 관리는 파일을 내부 경로와 데이터베이스 참조로 저장합니다. 우리는 다음을 수행하는 스크립트를 작성했습니다:

  1. Drupal 파일 디렉토리에서 모든 파일 다운로드
  2. Sanity의 자산 파이프라인으로 업로드
  3. 이전 Drupal 파일 ID를 새 Sanity 자산 참조로 매핑
  4. 새 자산 참조를 가리키도록 모든 리치 텍스트 콘텐츠 업데이트

이 스크립트는 전체 데이터셋에서 약 14시간 실행되었습니다. 우리는 프로젝트 동안 3번 실행했습니다: 초기 테스팅, 중간 지점에서 스테이징 새로고침, 최종 전환을 위해.

콘텐츠 프리즈 전략

우리는 2단계 콘텐츠 프리즈를 구현했습니다:

  • 1-20주: 콘텐츠 편집자는 Drupal에서 평상시대로 작업합니다. 우리는 주간 스냅샷을 스테이징으로 마이그레이션합니다.
  • 21-23주: 이중 입력. 새 콘텐츠는 Drupal과 Sanity 모두에 들어갑니다. 편집자는 새 CMS에서 훈련됩니다.
  • 24주: 완전 전환. Drupal은 읽기 전용이 되고 오프라인으로 갑니다.

이중 입력 기간은 고통스러웠지만 필요했습니다. 우리는 80명 이상의 편집자를 가지고 있었고, 유일한 옵션이 되기 전에 Sanity에서 근육 기억을 구축해야 했습니다.

6개월 타임라인

단계 주요 전달물
1월 발견 및 아키텍처 이해관계자 동의, CMS 선택, 인프라 설정, 콘텐츠 모델링
2월 핵심 개발 디자인 시스템, 페이지 템플릿, 프로그램 상세 페이지, 네비게이션
3월 프로그램 검색 및 검색 검색 인덱스, 필터링 UI, 프로그램 데이터 파이프라인, SEO 마크업
4월 학생 포탈 CAS 통합, Banner API 레이어, 대시보드, 학위 감시 표시
5월 콘텐츠 마이그레이션 및 교육 마이그레이션 스크립트, 편집자 교육 (6회), 스테이징 QA
6월 QA, 성능, 출시 로드 테스트, 접근성 감사, 콘텐츠 프리즈, DNS 전환

우리 팀은 4명의 개발자, 1명의 디자이너, 1명의 프로젝트 관리자였습니다. 대학교는 전담 제품 소유자와 Banner/CAS 통합 작업을 위한 IT 연락을 제공했습니다.

우리는 두 가지 주요 문제를 맞닥뜨렸습니다:

  1. 3월: Banner의 SOAP API는 분당 100개 요청의 문서화되지 않은 속도 제한을 가지고 있었습니다. 우리의 프로그램 검색은 빌드 중에 모든 프로그램 데이터를 일괄 페치하도록 설계되었습니다. 우리는 큐잉 시스템을 구현하고 여러 배치 전환에 걸쳐 빌드를 분산시켜야 했습니다.

  2. 5월: 접근성 감사에서 34개의 WCAG 2.1 AA 위반을 발견했습니다. 대부분은 디자인에서 상속되었습니다 (보조 버튼에 대한 불충분한 색상 대비, 프로그램 검색 필터의 초점 표시 누락). 우리는 예정되지 않은 8일을 개선에 소비했습니다.

성능 결과

출시 후 숫자는 다음과 같았습니다:

지표 Drupal 7 (이전) Next.js (이후) 개선
LCP 6.2s 1.1s 82% 더 빠름
FID / INP 380ms 45ms 88% 더 빠름
CLS 0.31 0.02 94% 개선
TTFB 2.8s 0.12s 96% 더 빠름
프로그램 검색 로드 8.4s 0.8s 90% 더 빠름
Lighthouse 점수 34 97 +63점
빌드 시간 (전체) N/A 4m 12s
월간 호스팅 비용 ~$2,400 ~$1,100 54% 낮음

하지만 대학교에 중요했던 숫자는 다음과 같습니다:

  • 프로그램 검색 사용량이 156% 증가 출시 후 첫 학기
  • 모바일 이탈률이 67%에서 31%로 하락
  • 프로그램 페이지에 대한 유기 검색 트래픽이 43% 증가 4개월 내 (schema.org 마크업 + Core Web Vitals 개선)
  • 포탈 관련 지원 티켓이 62% 감소 — 주로 페이지가 신뢰할 수 있게 로드되기 때문
  • 가을 등록 중 0의 다운타임 — 3년 만에 처음

배운 교훈

1. CAS/SSO 통합을 일찍 시작하세요

우리는 CAS 통합을 4월에 예정했습니다. 1월에 개념 증명을 시작했어야 합니다. 대학교 IT 팀은 보안 검토를 통해 의도적으로 (읽기: 느리게) 이동합니다. SSO 아키텍처를 승인받기 위해 그들의 보안 사무소와 3주의 왕복이 걸렸습니다.

2. 콘텐츠 모델링은 아키텍처입니다

우리는 프론트엔드 코드를 작성하기 전에 콘텐츠 모델링에 2주를 사용했습니다. 당시에는 느렸던 것 같았습니다. 우리가 한 최고의 투자였습니다. 200개 이상의 프로그램이 있고 학부, 단과대, 학위 수준, 농축, 전달 형식 간의 복잡한 관계가 있을 때, 스키마를 미리 올바르게 얻으면 리팩토링 시간을 수백 시간 절약합니다.

3. 출시 직전이 아니라 일찍 편집자를 교육하세요

우리는 원래 5월에 편집자 교육을 계획했습니다. 제품 소유자의 피드백 후 4월로 옮겼습니다. 이것은 편집자들이 2주 대신 6주 동안 Sanity에 익숙해질 기회를 제공했습니다. 이중 입력 기간 동안 입력된 콘텐츠의 품질은 이 때문에 극적으로 더 나았습니다.

4. Banner는 Banner입니다

Ellucian Banner (고등교육 기관에 있다면, 아마도 당신이 있습니다)와 작업 중이라면, API 통합을 위한 추가 시간을 예산하세요. 문서는 sparse이고, SOAP 엔드포인트는 일관성이 없으며, 모든 기관은 그들의 Banner 인스턴스를 다르게 커스터마이즈했습니다. 우리의 변환 레이어는 필수였습니다.

5. 처음부터 접근성을 위해 예산하세요

우리의 34개 WCAG 위반은 5월에 거의 대부분 예방 가능했습니다. 우리는 이제 모든 풀 요청에서 우리의 CI 파이프라인에서 axe-core 검사를 실행합니다. 공개 대학교를 위해 구축 중이라면, WCAG 2.1 AA 준수는 선택 사항이 아닙니다 — Section 508에 따른 법적 요구사항입니다.

유사한 마이그레이션 과제에 직면한 경우, 우리는 기꺼이 세부 사항을 통해 이야기할 수 있습니다. 당신은 우리에게 직접 연락할 수 있습니다 또는 우리의 가격 책정 페이지를 확인하여 우리가 이 프로젝트를 일반적으로 어떻게 범위 지정하는지 알아볼 수 있습니다.

자주 묻는 질문

Drupal에서 Next.js로 대학교 웹사이트를 마이그레이션하는 데 얼마나 걸립니까? 이 규모의 사이트 — 12,000개 콘텐츠 노드, 200개 이상의 프로그램, 인증 학생 포탈 — 4-6명의 전담 팀으로 6개월이 현실적입니다. 더 작은 기관 사이트 (2,000페이지 미만, 포탈 없음)는 종종 3-4개월 안에 완료할 수 있습니다. 타임라인은 프론트엔드 빌드보다는 콘텐츠 마이그레이션, 이해관계자 동의, Banner 또는 PeopleSoft와 같은 기관 시스템과의 통합으로 더 많이 결정됩니다.

고등교육 웹사이트에 최고의 헤드리스 CMS는 무엇입니까? 이것은 당신의 편집 팀의 크기와 기술적 편안함에 따라 다릅니다. 우리는 실시간 협업, 유연한 콘텐츠 모델링, GROQ 쿼리 언어 때문에 이 프로젝트를 위해 Sanity를 선택했습니다. Contentful과 Storyblok도 강력한 옵션입니다. 매우 큰 콘텐츠 팀 (100명 이상의 편집자)을 가진 대학교의 경우, Contentful의 워크플로우 및 권한 모델이 유리할 수 있습니다. 더 많은 커스터마이제이션을 원하는 작은 팀의 경우, Sanity는 일반적으로 우승합니다.

Next.js가 인증 학생 포탈을 처리할 수 있습니까? 절대. Next.js는 인증된 페이지를 위한 서버 측 렌더링을 지원하며, App Router의 서버 컴포넌트는 클라이언트 번들에 노출하지 않고 사용자 특화 데이터를 가져오는 것을 간단하게 만듭니다. 우리는 Auth.js와 함께 작성한 커스텀 공급자를 사용하여 CAS (Central Authentication Service)와 통합했습니다. 포탈은 성능 문제 없이 40,000명의 학생을 처리했습니다.

대학교를 위한 Drupal에서 Next.js로의 마이그레이션 비용은 얼마입니까? 이 범위의 프로젝트 — 프로그램 검색, 학생 포탈, 200개 이상의 프로그램, 전체 콘텐츠 마이그레이션, CMS 설정, 교육 — 일반적으로 복잡도에 따라 $250,000에서 $450,000 범위입니다. 그러나 장기 절약은 상당합니다. 이 대학교는 연간 유지보수 비용을 약 $180K에서 $95K로 줄였으므로, 프로젝트는 예산 범위의 상단에서도 3-4년 이내에 비용을 지불합니다.

대규모 CMS 마이그레이션 중 SEO에 어떤 일이 발생합니까? 이것은 정당한 우려입니다. 우리는 포괄적인 리디렉트 맵 (2,400개 이상의 301 리디렉트)을 구현했으며, 가능한 경우 모든 기존 URL 구조를 보존했고, Drupal 사이트에서 부족했던 schema.org 구조화된 데이터를 추가했습니다. 유기 트래픽은 출시 후 처음 2주에 약 8% 하락했습니다 (큰 마이그레이션에 정상적임), 그 후 4개월 이내에 기준선을 초과하여 43% 회복되었습니다.

대학교의 경우 Drupal 10이 헤드리스로 가는 것보다 더 좋은 선택입니까? 상황에 따라 그럴 수 있습니다. 팀이 강력한 Drupal 전문성을 가지고 있고, 커스텀 모듈이 Drupal 10 호환성을 가지고 있으며, 정적/하이브리드 사이트의 성능 특성을 필요로 하지 않는다면, Drupal 10은 완전히 유효한 경로입니다. 우리의 경우, 대학교는 Drupal 전문성을 잃었고, 23개의 호환되지 않는 모듈을 가지고 있었으며, 극적인 성능 개선이 필요했습니다. 헤드리스 접근은 명확히 더 나은 맞춤이었습니다.

Drupal에서 헤드리스 CMS로 콘텐츠를 마이그레이션하려면 어떻게 합니까? 우리는 Drush 명령을 통해 Drupal 콘텐츠를 내보내고, 새 CMS 스키마에 맞춰 데이터를 변환하고, 미디어 파일 마이그레이션을 처리하고, CMS의 마이그레이션 API를 통해 모든 것을 가져오는 커스텀 Node.js 스크립트를 사용합니다. 프로세스는 일반적으로 3번 실행됩니다: 초기 테스팅 1회, 스테이징 새로고침 1회, 최종 전환 1회. 포함된 미디어가 있는 리치 텍스트 콘텐츠가 가장 어려운 부분입니다 — 모든 내부 파일 참조를 다시 매핑해야 합니다.

마이그레이션 중에 Drupal과 Next.js를 동시에 실행할 수 있습니까? 네, 그리고 우리는 그것을 권장합니다. 마이그레이션 중, Drupal은 프로덕션 사이트를 계속 제공하는 동안 우리는 스테이징 도메인에서 Next.js 버전을 구축하고 테스트했습니다. 우리는 콘텐츠가 두 시스템 모두에 들어가는 3주 이중 입력 기간을 사용했습니다. 최종 전환은 약 15분이 걸리는 DNS 스위치였으며, 폴백으로 사용하기 위해 30일 동안 읽기 전용 모드로 유지된 Drupal입니다.