DocumentaciónAEMTutoriales de AEMTutorial de AEM sin encabezado

Aplicación React

Last update: Mon May 05 2025 00:00:00 GMT+0000 (Coordinated Universal Time)
  • Se aplica a:
  • Experience Manager as a Cloud Service
  • Temas:
  • Fragmentos de contenido

Creado para:

  • Principiante
  • Desarrollador

AEM Headless as a Cloud Service

Las aplicaciones de ejemplo son una buena manera de explorar las capacidades sin encabezado de Adobe Experience Manager (AEM). Esta aplicación de React muestra cómo consultar contenido mediante las API de GraphQL de AEM utilizando consultas persistentes. El cliente sin encabezado de AEM para JavaScript se utiliza para ejecutar las consultas persistentes de GraphQL que alimentan la aplicación.

Aplicación React con AEM Headless

Ver el código fuente en GitHub

Hay disponible un tutorial paso a paso que describe cómo se creó esta aplicación de React.

Requisitos previos

Las siguientes herramientas deben instalarse localmente:

  • Node.js v18
  • Git

Requisitos de AEM

La aplicación React funciona con las siguientes opciones de implementación de AEM. Todas las implementaciones requieren que esté instalado WKND Site v3.0.0+.

  • AEM as a Cloud Service
  • Configuración local mediante AEM Cloud Service SDK
    • Requiere JDK 11

La aplicación React está diseñada para conectarse a un entorno AEM Publish, pero puede obtener contenido de AEM Author si se proporciona autenticación en la configuración de la aplicación React.

Cómo usar

  1. Clonar el repositorio adobe/aem-guides-wknd-graphql:

    $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
    
  2. Edite el archivo aem-guides-wknd-graphql/react-app/.env.development y configure REACT_APP_HOST_URI para que apunte a su AEM de destino.

    Actualice el método de autenticación si se conecta a una instancia de autor.

    # Server namespace
    REACT_APP_HOST_URI=https://publish-p123-e456.adobeaemcloud.com
    
    #AUTH (Choose one method)
    # Authentication methods: 'service-token', 'dev-token', 'basic' or leave blank to use no authentication
    REACT_APP_AUTH_METHOD=basic
    
    # For Bearer auth, use DEV token (dev-token) from Cloud console
    REACT_APP_DEV_TOKEN=dev-token
    
    # For Service toke auth, provide path to service token file (download file from Cloud console)
    REACT_APP_SERVICE_TOKEN=auth/service-token.json
    
    # For Basic auth, use AEM ['user','pass'] pair (eg for Local AEM Author instance)
    REACT_APP_BASIC_AUTH_USER=admin
    REACT_APP_BASIC_AUTH_PASS=admin
    
  3. Abra un terminal y ejecute los comandos:

    $ cd aem-guides-wknd-graphql/react-app
    $ npm install
    $ npm start
    
  4. Se debe cargar una nueva ventana del explorador en http://localhost:3000

  5. En la aplicación se debe mostrar una lista de las aventuras del sitio de referencia de WKND.

El código

A continuación se muestra un resumen de cómo se crea la aplicación React, cómo se conecta a AEM Headless para recuperar contenido mediante consultas persistentes de GraphQL y cómo se presentan esos datos. El código completo se encuentra en GitHub.

Consultas persistentes

Siguiendo las prácticas recomendadas de AEM sin encabezado, la aplicación React utiliza consultas persistentes de AEM GraphQL para consultar datos de aventura. La aplicación utiliza dos consultas persistentes:

  • wknd/adventures-all persistió en la consulta, lo que devuelve todas las aventuras en AEM con un conjunto abreviado de propiedades. Esta consulta persistente genera la lista de aventuras de la vista inicial.
# 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 persistió en la consulta, lo que devuelve una sola aventura de slug (una propiedad personalizada que identifica de forma exclusiva una aventura) con un conjunto completo de propiedades. Esta consulta persistente activa las vistas de detalles de aventura.
# 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
      }
    }
  }
}

Ejecutar consulta persistente de GraphQL

Las consultas persistentes de AEM se ejecutan a través de HTTP GET y, por lo tanto, el cliente sin encabezado de AEM para JavaScript se usa para ejecutar las consultas de GraphQL persistentes en AEM y cargar el contenido de aventura en la aplicación.

Cada consulta persistente tiene un vínculo React useEffect correspondiente en src/api/usePersistedQueries.js, que llama asincrónicamente al punto final de la consulta persistente HTTP GET de AEM y devuelve los datos de la aventura.

A su vez, cada función invoca aemHeadlessClient.runPersistedQuery(...) y ejecuta la consulta de GraphQL persistente.

// src/api/usePersistedQueries.js

/**
 * React custom hook that returns a list of adevntures by activity. If no activity is provided, all adventures are returned.
 *
 * Custom hook that calls the 'wknd-shared/adventures-all' or 'wknd-shared/adventures-by-activity' persisted query.
 *
 * @returns an array of Adventure JSON objects, and array of errors
 */
export function useAdventuresByActivity(adventureActivity, params = {}) {
  ...
  let queryVariables = params;

  // If an activity is provided (i.e "Camping", "Hiking"...) call wknd-shared/adventures-by-activity query
  if (adventureActivity) {
    // The key is 'activity' as defined in the persisted query
    queryVariables = { ...queryVariables, activity: adventureActivity };

    // Call the AEM GraphQL persisted query named "wknd-shared/adventures-by-activity" with parameters
    response = await fetchPersistedQuery("wknd-shared/adventures-by-activity", queryVariables);
  } else {
    // Else call the AEM GraphQL persisted query named "wknd-shared/adventures-all" to get all adventures
    response = await fetchPersistedQuery("wknd-shared/adventures-all", queryVariables);
  }

  ...
}

...
/**
 * Private function that invokes the AEM Headless client.
 *
 * @param {String} persistedQueryName the fully qualified name of the persisted query
 * @param {*} queryParameters an optional JavaScript object containing query parameters
 * @returns the GraphQL data or an error message
 */
async function fetchPersistedQuery(persistedQueryName, queryParameters) {
  let data;
  let err;

  try {
    // AEM GraphQL queries are asynchronous, either await their return or use Promise-based .then(..) { ... } syntax
    const response = await aemHeadlessClient.runPersistedQuery(
      persistedQueryName,
      queryParameters
    );
    // The GraphQL data is stored on the response's data field
    data = response?.data;
  } catch (e) {
    // An error occurred, return the error messages
    err = e
      .toJSON()
      ?.map((error) => error.message)
      ?.join(", ");
    console.error(e.toJSON());
  }

  return { data, err };
}

Vistas

La aplicación React utiliza dos vistas para presentar los datos de la aventura en la experiencia web.

  • src/components/Adventures.js

    Invoca getAdventuresByActivity(..) desde src/api/usePersistedQueries.js y muestra las aventuras devueltas en una lista.

  • src/components/AdventureDetail.js

    Invoca a getAdventureBySlug(..) mediante el parámetro slug pasado mediante la selección de aventuras en el componente Adventures y muestra los detalles de una sola aventura.

Variables del entorno

Se usan varias variables de entorno para conectarse a un entorno de AEM. De forma predeterminada, se conecta a la publicación de AEM que se ejecuta en http://localhost:4503. Actualice el archivo .env.development para cambiar la conexión de AEM:

  • REACT_APP_HOST_URI=https://publish-p123-e456.adobeaemcloud.com: establecido en el host de destino de AEM

  • REACT_APP_GRAPHQL_ENDPOINT=/content/graphql/global/endpoint.json: establezca la ruta de acceso del extremo de GraphQL. Esta aplicación de React no la utiliza, ya que solo utiliza consultas persistentes.

  • REACT_APP_AUTH_METHOD=: método de autenticación preferido. Opcional. De forma predeterminada, no se utiliza ninguna autenticación.

    • service-token: use las credenciales del servicio para obtener un token de acceso en AEM as a Cloud Service
    • dev-token: use el token de desarrollo para el desarrollo local en AEM as a Cloud Service
    • basic: usar usuario/pase para el desarrollo local con el autor local de AEM
    • Déjelo en blanco para conectarse a AEM sin autenticación
  • REACT_APP_AUTHORIZATION=admin:admin: establezca las credenciales de autenticación básicas que se usarán si se conecta a un entorno de AEM Author (solo para desarrollo). Si se conecta a un entorno de publicación, esta configuración no es necesaria.

  • REACT_APP_DEV_TOKEN: cadena de token de desarrollador. Para conectarse a una instancia remota, además de la autenticación básica (user:pass), puede utilizar la autenticación del portador con el token de DEV de la consola de Cloud

  • REACT_APP_SERVICE_TOKEN: ruta al archivo de credenciales de servicio. Para conectarse a una instancia remota, la autenticación también se puede realizar con el token de servicio (descargue el archivo desde Developer Console).

Solicitudes de AEM de proxy

Al usar el servidor de desarrollo de Webpack (npm start), el proyecto depende de una configuración proxy que usa http-proxy-middleware. El archivo está configurado en src/setupProxy.js y depende de varias variables de entorno personalizadas establecidas en .env y .env.development.

Si se conecta a un entorno de AEM Author, el método de autenticación correspondiente debe configurarse.

Uso compartido de recursos de origen cruzado (CORS)

Esta aplicación React se basa en una configuración CORS basada en AEM que se ejecuta en el entorno AEM de destino y supone que la aplicación React se ejecuta en http://localhost:3000 en modo de desarrollo. Consulte la documentación de implementación sin encabezado de AEM para obtener más información sobre cómo configurar CORS.

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