Next.js-app

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

Voorbeeldtoepassingen zijn een geweldige manier om de mogelijkheden zonder kop van Adobe Experience Manager (AEM) te verkennen. Deze toepassing Next.js toont aan hoe te om inhoud te vragen gebruikend AEM GraphQL APIs gebruikend persisted query's. De AEM Headless-client voor JavaScript wordt gebruikt om de GraphQL-doorlopende query's uit te voeren die de toepassing van stroom voorzien.

Next.js app met AEM Headless

Bekijk de broncode op GitHub

Vereisten prerequisites

De volgende gereedschappen moeten lokaal worden geïnstalleerd:

AEM

De app Next.js werkt met de volgende AEM implementatieopties. Alle plaatsingen vereisen Gedeelde v3.0.0+WKND van de Plaats v3.0.0+ 🔗 om op het milieu van AEM as a Cloud Service worden geïnstalleerd.

Dit voorbeeld Next.js app wordt ontworpen om met AEM de dienst van Publish te verbinden.

Vereisten AEM auteur

Next.js wordt ontworpen om met AEM de dienst van Publish te verbinden, en tot onbeschermde inhoud toegang te hebben. Next.js kan worden gevormd om met AEM Auteur via de .env hieronder beschreven eigenschappen te verbinden. Voor afbeeldingen die worden aangeboden door AEM auteur is verificatie vereist. De gebruiker die de Next.js-app opent, moet daarom ook zijn aangemeld bij AEM auteur.

Hoe wordt het gebruikt

  1. De gegevensopslagruimte adobe/aem-guides-wknd-graphql klonen:

    code language-shell
    $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
    
  2. Bewerk het aem-guides-wknd-graphql/next-js/.env.local -bestand en stel NEXT_PUBLIC_AEM_HOST in op de AEM-service.

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

    Als u verbinding maakt met AEM service Auteur, moet de verificatie worden opgegeven omdat AEM service Auteur standaard is beveiligd.

    Een lokale AEM gebruiken AEM_AUTH_METHOD=basic en de gebruikersnaam en het wachtwoord opgeven in de eigenschappen AEM_AUTH_USER en 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 een AEM as a Cloud Service lokaal ontwikkelingstokente gebruiken plaats AEM_AUTH_METHOD=dev-token en de volledige dev symbolische waarde in het AEM_AUTH_DEV_TOKEN bezit te verstrekken.

    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. Bewerk het aem-guides-wknd-graphql/next-js/.env.local -bestand en valideer NEXT_PUBLIC_AEM_GRAPHQL_ENDPOINT op het juiste AEM GraphQL-eindpunt.

    Wanneer het gebruiken van Gedeelde WKNDof Plaats WKND, gebruik het wknd-shared GraphQL API eindpunt.

    code language-plain
    ...
    NEXT_PUBLIC_AEM_GRAPHQL_ENDPOINT=wknd-shared
    ...
    
  4. Open een bevelherinnering en begin volgende.js app gebruikend de volgende bevelen:

    code language-shell
    $ cd aem-guides-wknd-graphql/next-js
    $ npm install
    $ npm run dev
    
  5. Een nieuw browser venster opent Next.js app in http://localhost:3000

  6. De app Next.js geeft een lijst met avonturen weer. Als u een avontuur selecteert, worden de details op een nieuwe pagina weergegeven.

De code

Hieronder volgt een overzicht van de manier waarop de toepassing Next.js is gemaakt, hoe deze verbinding maakt met AEM Headless om inhoud op te halen met behulp van GraphQL persisted query's en hoe deze gegevens worden gepresenteerd. De volledige code kan op GitHubworden gevonden.

Blijvende query's

Na AEM Beste praktijken zonder hoofd, gebruikt de toepassing Next.js AEM GraphQL voortgezette vragen om avontuurgegevens te vragen. De toepassing gebruikt twee doorlopende query's:

  • wknd/adventures-all persisted query, die alle avonturen in AEM met een verkorte set eigenschappen retourneert. Deze hardnekkige vraag drijft de aanvankelijke lijst van het avontuur van de mening.
# 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 persisted query, die één avontuur retourneert van slug (een aangepaste eigenschap die een avontuur op unieke wijze identificeert) met een volledige set eigenschappen. Dit bleef vraagbevoegdheden de meningen van het avontuurdetail.
# 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-query uitgevoerd

AEM voortgeduurde vragen worden uitgevoerd over de GET van HTTP en zo, wordt de AEM Draadloze cliënt voor JavaScriptgebruikt om de voortgeduurde vragen van GraphQLtegen AEM uit te voeren en de avontuurinhoud in app te laden.

Elke voortgeduurde vraag heeft een overeenkomstige functie in src/lib//aem-headless-client.js, die het eindpunt van AEM GraphQL roept, en de avontuurgegevens terugkeert.

Elke functie roept op zijn beurt de aemHeadlessClient.runPersistedQuery(...) aan, die de voortgezette GraphQL query uitvoert.

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

Pagina's

De app Next.js gebruikt twee pagina's om de avontuurgegevens te presenteren.

  • src/pages/index.js

    Gebruikt Next.js getServerSideProps ()om getAllAdventures() te roepen en toont elk avontuur als kaart.

    Het gebruik van getServerSiteProps() staat voor server-zij Rendering van deze pagina Next.js toe.

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

    A Next.js Dynamische Routedie de details van één enkel avontuur toont. Deze dynamische route prefetches de gegevens van elk avontuur gebruikend Next.js getStaticProps ()via een vraag aan getAdventureBySlug(slug, queryVariables) gebruikend slug param dat via de avontuurselectie op de adventures/index.js pagina wordt overgegaan, en queryVariables om het beeldformaat, de breedte, en de kwaliteit te controleren.

    De dynamische route kan de details voor alle avonturen pre-halen door te gebruiken Next.js getStaticPaths ()en het bevolken van alle mogelijke routepermutaties die op de volledige lijst van avonturen worden gebaseerd door de vraag van GraphQL getAdventurePaths() zijn teruggekeerd

    Het gebruik van getStaticPaths() en getStaticProps(..) stond de Statische Generatie van de Plaats van deze pagina's toe Next.js.

Implementatieconfiguratie

Voor Next.js-apps, met name in de context van server-side rendering (SSR) en server-side generation (SSG), zijn geen geavanceerde beveiligingsconfiguraties vereist, zoals Cross-origin Resource Sharing (CORS).

Nochtans, als Next.js HTTP- verzoeken aan AEM van de context van de cliënt doet, kunnen de veiligheidsconfiguraties in AEM worden vereist. Herzie het AEM Headless enig-pagina de plaatsingsleerprogramma van de appvoor meer details.

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