Next.js 앱

AEM 헤드리스 as a Cloud Service

예제 애플리케이션은 AEM(Adobe Experience Manager)의 Headless 기능을 살펴볼 수 있는 좋은 방법입니다. 이 Next.js 애플리케이션은 지속 쿼리를 사용하여 AEM GraphQL API를 사용하여 콘텐츠를 쿼리하는 방법을 보여 줍니다. JavaScript용 AEM Headless 클라이언트는 앱을 구동하는 GraphQL 지속 쿼리를 실행하는 데 사용됩니다.

AEM Headless가 포함된 Next.js 앱

보기 gitHub의 소스 코드

사전 요구 사항 prerequisites

다음 도구를 로컬에 설치해야 합니다.

AEM 요구 사항

Next.js 앱은 다음 AEM 배포 옵션과 함께 작동합니다. 모든 배포에는 WKND 공유 v3.0.0+ 또는 WKND 사이트 v3.0.0+ AEM as a Cloud Service 환경에 설치됩니다.

이 예제 Next.js 앱은에 연결하도록 설계되었습니다. AEM 게시 서비스.

AEM 작성자 요구 사항

Next.js는에 연결하도록 설계되었습니다. AEM 게시 서비스 및 보호되지 않은 콘텐츠에 액세스 다음을 통해 AEM 작성자에 연결하도록 Next.js를 구성할 수 있습니다. .env 아래에 설명된 속성입니다. AEM Author에서 제공하는 이미지는 인증이 필요하므로 Next.js 앱에 액세스하는 사용자도 AEM Author에 로그인해야 합니다.

사용 방법

  1. 복제 adobe/aem-guides-wknd-graphql 저장소:

    code language-shell
    $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
    
  2. 편집 aem-guides-wknd-graphql/next-js/.env.local 파일 및 세트 NEXT_PUBLIC_AEM_HOST AEM 서비스로 이동합니다.

    code language-plain
    # AEM service
    NEXT_PUBLIC_AEM_HOST=https://publish-p123-e456.adobeaemcloud.com/
    ...
    

    AEM Author 서비스에 연결하는 경우 AEM Author 서비스는 기본적으로 안전하므로 인증을 제공해야 합니다.

    로컬 AEM 계정 세트를 사용하려면 AEM_AUTH_METHOD=basic 및 는에서 사용자 이름과 암호를 제공합니다. AEM_AUTH_USERAEM_AUTH_PASSWORD 속성.

    code language-plain
    ...
    # The variables are not prefixed with NEXT_PUBLIC so they are only available server-side
    AEM_AUTH_METHOD=basic
    AEM_AUTH_USER=aem-user-account
    AEM_AUTH_PASSWORD=password-for-the-aem-user-account
    

    을(를) 사용하려면 AEM as a Cloud Service 로컬 개발 토큰 set AEM_AUTH_METHOD=dev-token 에서 전체 개발 토큰 값을 제공합니다. AEM_AUTH_DEV_TOKEN 속성.

    code language-plain
    ...
    # The variables are not prefixed with NEXT_PUBLIC so they are only available server-side
    AEM_AUTH_METHOD=dev-token
    AEM_AUTH_DEV_TOKEN=my-dev-token
    
  3. 편집 aem-guides-wknd-graphql/next-js/.env.local 파일 및 유효성 검사 NEXT_PUBLIC_AEM_GRAPHQL_ENDPOINT 가 적절한 AEM GraphQL 종단점으로 설정되어 있습니다.

    사용 시 WKND 공유 또는 WKND 사이트, 사용 wknd-shared GraphQL API 엔드포인트.

    code language-plain
    ...
    NEXT_PUBLIC_AEM_GRAPHQL_ENDPOINT=wknd-shared
    ...
    
  4. 명령 프롬프트를 열고 다음 명령을 사용하여 Next.js 앱을 시작합니다.

    code language-shell
    $ cd aem-guides-wknd-graphql/next-js
    $ npm install
    $ npm run dev
    
  5. 새 브라우저 창에서 다음.js 앱이 열립니다. http://localhost:3000

  6. Next.js 앱은 모험 목록을 표시합니다. 모험을 선택하면 해당 세부 정보가 새 페이지에 열립니다.

코드

다음은 Next.js 앱이 빌드되는 방법, GraphQL 지속 쿼리를 사용하여 콘텐츠를 검색하기 위해 AEM Headless에 연결하는 방법 및 이러한 데이터가 표시되는 방법에 대한 요약입니다. 전체 코드는에서 찾을 수 있습니다 GitHub.

지속 쿼리

AEM Headless 모범 사례에 따라 Next.js 앱은 AEM GraphQL 지속 쿼리를 사용하여 어드벤처 데이터를 쿼리합니다. 이 앱에서는 두 개의 지속 쿼리를 사용합니다.

  • wknd/adventures-all 지속 쿼리 - 속성 세트가 간략히 포함되어 AEM의 모든 모험을 반환합니다. 이 지속 쿼리는 초기 보기의 모험 목록을 구동합니다.
# Retrieves a list of all Adventures
#
# Optional query variables:
# - { "offset": 10 }
# - { "limit": 5 }
# - {
#    "imageFormat": "JPG",
#    "imageWidth": 1600,
#    "imageQuality": 90
#   }
query ($offset: Int, $limit: Int, $sort: String, $imageFormat: AssetTransformFormat=JPG, $imageWidth: Int=1200, $imageQuality: Int=80) {
  adventureList(
    offset: $offset
    limit: $limit
    sort: $sort
    _assetTransform: {
      format: $imageFormat
      width: $imageWidth
      quality: $imageQuality
      preferWebp: true
  }) {
    items {
      _path
      slug
      title
      activity
      price
      tripLength
      primaryImage {
        ... on ImageRef {
          _path
          _dynamicUrl
        }
      }
    }
  }
}
  • wknd/adventure-by-slug 지속 쿼리 - 단일 모험 반환 기준 slug (모험을 고유하게 식별하는 사용자 지정 속성) 전체 속성 세트를 포함합니다. 이 지속 쿼리는 모험 세부 사항 보기를 실행합니다.
# Retrieves an Adventure Fragment based on it's unique slug.
#
# Required query variables:
# - {"slug": "bali-surf-camp"}
#
# Optional query variables:
# - {
#     "imageFormat": "JPG",
#     "imageSeoName": "my-adventure",
#     "imageWidth": 1600,
#     "imageQuality": 90
#   }
#
# This query returns an adventure list but since the the slug property is set to be unique in the Content Fragment Model, only a single Content Fragment is expected.

query ($slug: String!, $imageFormat:AssetTransformFormat=JPG, $imageSeoName: String, $imageWidth: Int=1200, $imageQuality: Int=80) {
  adventureList(
    filter: {slug: {_expressions: [{value: $slug}]}}
    _assetTransform: {
      format: $imageFormat
      seoName: $imageSeoName
      width: $imageWidth
      quality: $imageQuality
      preferWebp: true
  }) {
    items {
      _path
      title
      slug
      activity
      adventureType
      price
      tripLength
      groupSize
      difficulty
      price
      primaryImage {
        ... on ImageRef {
          _path
          _dynamicUrl
        }
      }
      description {
        json
        plaintext
        html
      }
      itinerary {
        json
        plaintext
        html
      }
    }
    _references {
      ... on AdventureModel {
        _path
        slug
        title
        price
        __typename
      }
    }
  }
}

GraphQL 지속 쿼리 실행

AEM 지속 쿼리는 HTTP GET을 통해 실행되므로 JavaScript용 AEM Headless 클라이언트 다음에 사용됨: 지속 GraphQL 쿼리 실행 AEM에 대해 를 검색하고 어드벤처 콘텐츠를 앱에 로드합니다.

각 지속 쿼리는에 해당 함수가 있습니다. src/lib//aem-headless-client.js를 호출하여 AEM GraphQL 끝점을 호출하고 어드벤처 데이터를 반환합니다.

각 함수는 차례로 aemHeadlessClient.runPersistedQuery(...): 지속 GraphQL 쿼리를 실행합니다.

// src/lib/aem-headless-client.js

...
/**
 * Invokes the 'adventures-all` persisted query using the parameterizable namespace.
 *
 * @returns a GraphQL response of all adventures.
 */
async getAllAdventures() {
  const queryAdventuresAll = process.env.NEXT_PUBLIC_AEM_GRAPHQL_ENDPOINT + '/adventures-all';

  try {
    return await this.aemHeadlessClient.runPersistedQuery(queryAdventuresAll);
  } catch(e) {
    console.error(e)
  }
}

// And so on, and so forth ...

async getAdventureSlugs(queryVariables) { ... }

async getAdventuresBySlug(slug, queryVariables) { ... }
...

페이지

Next.js 앱은 두 페이지를 사용하여 모험 데이터를 제공합니다.

  • src/pages/index.js

    사용 Next.js의 getServerSideProps() 호출하기 getAllAdventures() 각 모험을 카드로 표시합니다.

    사용 getServerSiteProps() 이 Next.js 페이지의 서버측 렌더링을 허용합니다.

  • src/pages/adventures/[...slug].js

    A Next.js 동적 경로 단일 모험의 세부 정보를 표시합니다. 이 동적 경로는 다음을 사용하여 각 모험의 데이터를 미리 가져옵니다. Next.js의 getStaticProps() (으)로 호출을 통해 getAdventureBySlug(slug, queryVariables) 사용 slug 에서 모험 선택을 통해 전달된 매개 변수 adventures/index.js 페이지 및 queryVariables 이미지 형식, 너비 및 품질을 제어합니다.

    동적 경로는 를 사용하여 모든 모험에 대한 세부 사항을 미리 가져올 수 있습니다. Next.js의 getStaticPaths() GraphQL 쿼리에서 반환한 모험의 전체 목록을 기반으로 가능한 모든 경로 순열 채우기 getAdventurePaths()

    사용 getStaticPaths()getStaticProps(..) 다음 Next.js 페이지의 정적 사이트 생성을 허용했습니다.

배포 구성

특히 서버측 렌더링(SSR) 및 서버측 생성(SSG)의 컨텍스트에서 Next.js 앱은 CORS(원본 간 리소스 공유)와 같은 고급 보안 구성이 필요하지 않습니다.

그러나 Next.js가 클라이언트의 컨텍스트에서 AEM에 HTTP 요청을 하는 경우 AEM의 보안 구성이 필요할 수 있습니다. 리뷰 AEM Headless 단일 페이지 앱 배포 튜토리얼 을 참조하십시오.

recommendation-more-help
e25b6834-e87f-4ff3-ba56-4cd16cdfdec4