Next.js App

[AEM as a Cloud Service]{class="badge informative"}

Exempelprogram är ett bra sätt att utforska Adobe Experience Manager headless-funktioner (AEM). I det här Next.js-programmet visas hur du kan söka efter innehåll med hjälp av AEM GraphQL API:er med beständiga frågor. AEM Headless Client för JavaScript används för att köra de beständiga GraphQL-frågor som stöder appen.

appen Next.js med AEM Headless

Visa källkoden på GitHub

Förutsättningar prerequisites

Följande verktyg bör installeras lokalt:

AEM

Appen Next.js fungerar med följande AEM driftsättningsalternativ. För alla distributioner krävs att WKND Shared v3.0.0+ eller WKND Site v3.0.0+ installeras i AEM as a Cloud Service-miljön.

Det här exemplet på appen Next.js är utformat för att ansluta till tjänsten AEM Publish.

Krav för AEM författare

Next.js är utformad för att ansluta till AEM Publish-tjänsten och få åtkomst till oskyddat innehåll. Next.js kan konfigureras att ansluta till AEM Author via egenskaperna .env som beskrivs nedan. Bilder som hanteras från AEM författare kräver autentisering, och därför måste användaren som använder appen Next.js också loggas in AEM Author.

Så här använder du

  1. Klona adobe/aem-guides-wknd-graphql-databasen:

    code language-shell
    $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
    
  2. Redigera filen aem-guides-wknd-graphql/next-js/.env.local och ange NEXT_PUBLIC_AEM_HOST till AEM.

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

    Om du ansluter till AEM Author-tjänsten måste du ange AEM Author-tjänsten som standard.

    Om du vill använda en lokal AEM AEM_AUTH_METHOD=basic och ange användarnamn och lösenord i egenskaperna AEM_AUTH_USER och AEM_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
    

    Om du vill använda en lokal utvecklingstoken från AEM as a Cloud Service anger du AEM_AUTH_METHOD=dev-token och anger det fullständiga dev-tokenvärdet i egenskapen 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. Redigera filen aem-guides-wknd-graphql/next-js/.env.local och validera att NEXT_PUBLIC_AEM_GRAPHQL_ENDPOINT är inställt på rätt AEM GraphQL-slutpunkt.

    Använd GraphQL API-slutpunkten wknd-shared när du använder WKND delad eller WKND-plats.

    code language-plain
    ...
    NEXT_PUBLIC_AEM_GRAPHQL_ENDPOINT=wknd-shared
    ...
    
  4. Öppna en kommandotolk och starta appen Next.js med följande kommandon:

    code language-shell
    $ cd aem-guides-wknd-graphql/next-js
    $ npm install
    $ npm run dev
    
  5. Ett nytt webbläsarfönster öppnar appen Next.js på http://localhost:3000

  6. I appen Next.js visas en lista med äventyr. Om du väljer ett äventyr öppnas informationen på en ny sida.

Koden

Nedan följer en sammanfattning av hur appen Next.js byggs, hur den ansluter till AEM Headless för att hämta innehåll med GraphQL beständiga frågor och hur data presenteras. Den fullständiga koden finns på GitHub.

Beständiga frågor

Efter AEM Headless-metodtips använder appen Next.js AEM GraphQL beständiga frågor för att fråga efter äventyrsdata. Appen använder två beständiga frågor:

  • wknd/adventures-all beständig fråga, som returnerar alla äventyr i AEM med en förkortad uppsättning egenskaper. Den här beständiga frågan styr den inledande vyns äventyrslista.
# 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 beständig fråga, som returnerar ett enskilt äventyr från slug (en anpassad egenskap som unikt identifierar ett äventyr) med en fullständig uppsättning egenskaper. Den här beständiga frågan styr äventyrsdetaljvyerna.
# 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
      }
    }
  }
}

Kör GraphQL beständig fråga

AEM beständiga frågor körs via HTTP-GET och därför används klienten AEM Headless för JavaScript för att köra de beständiga GraphQL-frågorna mot AEM och läsa in äventyrsinnehållet i appen.

Varje beständig fråga har en motsvarande funktion i src/lib//aem-headless-client.js, som anropar den AEM GraphQL-slutpunkten och returnerar äventyrsdata.

Varje funktion anropar i sin tur aemHeadlessClient.runPersistedQuery(...) och kör den beständiga GraphQL-frågan.

// 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) { ... }
...

Sidor

Appen Next.js använder två sidor för att presentera äventyrsdata.

  • src/pages/index.js

    Använder Next.js getServerSideProps() för att anropa getAllAdventures() och visar varje äventyr som ett kort.

    Användning av getServerSiteProps() tillåter återgivning på serversidan av den här Next.js-sidan.

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

    En dynamisk väg för Next.js som visar information om ett enskilt äventyr. Den här dynamiska vägen förhämtar data för varje äventyr med hjälp av Next.js getStaticProps() via ett anrop till getAdventureBySlug(slug, queryVariables) med hjälp av den slug -parameter som skickas via äventyrsmarkeringen på adventures/index.js -sidan och queryVariables för att styra bildformatet, bredden och kvaliteten.

    Den dynamiska vägen kan förhämta information för alla äventyr genom att använda Next.js getStaticPaths() och fylla i alla möjliga vägpermutationer baserat på den fullständiga listan över äventyr som returneras av GraphQL-frågan getAdventurePaths()

    Användningen av getStaticPaths() och getStaticProps(..) tillät generering av statiska platser för dessa Next.js-sidor.

Distributionskonfiguration

Next.js-appar, särskilt när det gäller SSR (Server-side rendering) och SSG (Server-side generation), kräver inte avancerade säkerhetskonfigurationer som CORS (Cross-origin Resource Sharing).

Om Next.js däremot gör HTTP-begäranden till AEM från klientens kontext kan säkerhetskonfigurationer i AEM behövas. Mer information finns i självstudiekursen AEM Headless Single-page app deployment.

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