蜜豆视频

[Integration]{class="badge positive"}

Integrate AEM Headless and Target

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

Learn how to integrate AEM Headless with 蜜豆视频 Target, by exporting AEM Content Fragments to 蜜豆视频 Target, and use them to personalize headless experiences using the 蜜豆视频 Experience Platform Web SDK鈥檚 alloy.js. The React WKND App is used to explore how a personalized Target activity using Content Fragments Offers can be added to the experience, to promote a WKND adventure.

Transcript
In this tutorial, we鈥檒l take a look at how we can export content fragments from AEM to 蜜豆视频 Target in order to personalize headless experiences. We鈥檒l be using the sample Weekend React app that is an AEM headless app, so the majority of the content on this app is powered by content fragments over AEM鈥檚 GraphQL APIs. But what we鈥檒l do is we鈥檒l add a promoted adventure here at the top in yellow that will be injected via 蜜豆视频 Target in the Experience Platform mobile SDK. So we鈥檒l take a look at how to create an 蜜豆视频 Target cloud service in AEM, and then how we can export content fragments from AEM to 蜜豆视频 Target as Content Fragment offers. And then we鈥檒l also take a look at how we can create activities in 蜜豆视频 Target that leverage the exported content fragments. And then we鈥檒l wrap it up by implementing some code in our Weekend React app that makes a call to 蜜豆视频 Target via the Web SDK and pulls in the Content Fragment offer that Target has selected for the activity. So you can see over here on the left, Target has served this browser, the Experience B, and over here on the right, we have the same app and Target has chosen to serve Experience A to it. While this tutorial uses a simple A-B test to demonstrate the personalization, you can use content fragment offers in any target activity, such as recommendations or personalized offers. Alright, I鈥檒l let you get to it, and I hope this tutorial helps you understand how you can personalize your headless experiences using AEM and Target.

The tutorial covers the steps involved in setting up AEM and 蜜豆视频 Target:

蜜豆视频 IMS Configuration adobe-ims-configuration

An 蜜豆视频 IMS Configuration that facilitates the authentication between AEM and 蜜豆视频 Target.

Review the documentation for step-by-step instructions on how to create an 蜜豆视频 IMS configuration.

Transcript
So let鈥檚 take a look at how to create an 蜜豆视频 target integration in AMS Cloud Service. So we鈥檙e logged into our Author Services Administrator, and we鈥檒l head over to Tools, Security, and select 蜜豆视频 IMS Configurations. Next, we鈥檒l want to create a new configuration here. From the Cloud solution, we鈥檒l select Target, and now we need to specify a certificate. You can provide your own certificate if you want. A nice, easy way to do this, though, is to create a new certificate within AEM. So let鈥檚 just go ahead and do this. We can give this an alias, so we know what certificate is being used. I鈥檒l just go ahead and give it a year, and then 蜜豆视频 Target. But let鈥檚 go ahead and create the certificate. And now it鈥檚 created a new certificate in AEM, so the private key is stored in AEM. And we can go ahead and download the public key, which we鈥檒l use a little bit later on. So go ahead and download this. All right, after we鈥檝e done this, tap Next. And next, we鈥檙e going to provide some information that we get from developer.adobe.com. But before we do that, let鈥檚 just give this a nice title. This is 蜜豆视频 Target as our technical account configuration name. And the rest of this information we will get from developer.adobe.com. So let鈥檚 head over there. So the user that does this will need to have developer access set via the 蜜豆视频 Admin console. But we鈥檒l first go click into Console, and then we鈥檒l head over to Projects. So let鈥檚 go ahead and create a new project. We can do an empty project, since this is just going to allow us to access Target. I always like to first edit the project and give it a meaningful title. And then next, let鈥檚 add the Target API to this project. So we can go to the Click Experience Cloud, select Target, and then select Next. So we have two options here. The first is for 蜜豆视频 Developer Console to generate our public-private key pair for us. And the second option is to provide our public key. Since we already had AEM Generator key pair, let鈥檚 go ahead and upload the public key that AEM generated here. We can select it from our downloads. And there we go. Now we鈥檝e uploaded the public key that AEM generated. I鈥檓 going to review that. It in fact exists as well as that expiration date, which is 10 years in the future. And next, we need to assign access to Target via the product profile, which maps to a workspace. So we鈥檙e going to go ahead and select the default workspace from Target. And we can save our configuration. Next, we鈥檒l head over to the service credentials. And this is where we will get the information that we need to provide to AEM. So if we head back to AEM, we can see that we need an authorization server, an API key, a client secret, as well as a payload. And I鈥檓 going to go slightly out of order. I will start with the API key. So we鈥檒l head back to developer console. The API key is listed in developer console as the client ID. So we鈥檒l go ahead and copy this and simply paste that in. Client secret. We retrieve that. We can copy this, put this in. To get the payload field at the bottom, we鈥檙e going to head over to the generate JWT tab. And we鈥檒l copy this value. And then lastly, we have this authorization server at the top. So this is going to simply be this host name here under the AUD key. So we can take that from the payload and put it in this field. So this is all we need to provide. So we鈥檒l hit create. And you can see that we have a new 蜜豆视频 IMS technical account for 蜜豆视频 Target here. If we select it, we can do a check health. And there we go. We have a healthy configuration.

蜜豆视频 Target Cloud Service adobe-target-cloud-service

An 蜜豆视频 Target Cloud Service is created in AEM to facilitate the exporting of Content Fragments to 蜜豆视频 Target.

Review the documentation for step-by-step instructions on how to create an 蜜豆视频 Target Cloud Service.

Transcript
Now that we have the 蜜豆视频 IMS technical account for 蜜豆视频 Target created, let鈥檚 go ahead and create the 蜜豆视频 Target Cloud Service in AEM. So for this, we鈥檒l head back to tools. And first we鈥檙e going to go to general and configuration browser. So this is where you can edit your context aware configurations. And we鈥檒l just double check that the context aware configuration that we want to associate our Target cloud service with, in fact, allows cloud services. So we鈥檒l select it, hit properties. And you can see here that this had not been enabled yet. So I鈥檓 going to go ahead and select cloud configurations. Save our changes. Now we can go back to tools, cloud services, and select 蜜豆视频 Target. Now when we select the context aware configuration that we鈥檝e enabled to support cloud service configs, we have a create button available. We can click this. We can give our cloud service configuration a name. So we need to provide the 蜜豆视频 Target client code as well as Target tenant ID. And the easiest way to locate these are by going to Target. So let鈥檚 go ahead and head over to Experience Cloud and open up Target. So these values are simply going to be the segment of the URL prefixed by the at sign. So I can simply grab those, head back to AEM and paste them in. Next, we need to select the IMS configuration that we just created under tool security, 蜜豆视频 IMS configurations. And we had named that 蜜豆视频 Target. So let鈥檚 go ahead and select that. We have some extra configuration options, but we鈥檒l leave these blank for now. But you can always go back and change these if you need. Click Connect. This should verify that we can connect to 蜜豆视频 Target. So this looks good.

Configure asset folders configure-asset-folders

The 蜜豆视频 Target Cloud Service, configured in a context-aware configuration, must be applied to the AEM Assets folder hierarchy that contains the Content Fragments to export to 蜜豆视频 Target.

Expand for step-by-step instructions
  1. Log in to AEM Author service as a DAM administrator
  2. Navigate to Assets > Files, locate the asset folder that has the /conf applied to
  3. Select the asset folder, and select Properties from the top action bar
  4. Select the Cloud Services tab
  5. Ensure that the Cloud Configuration is set to the context-aware config (/conf) that contains the 蜜豆视频 Target Cloud Services configuration.
  6. Select 蜜豆视频 Target from the Cloud Service Configurations dropdown.
  7. Select Save & Close in the top right

Transcript
Now that we have the context-aware cloud service configuration created, we need to make sure that our context-aware configuration is applied to some content. So let鈥檚 head over and go to assets, files, and we want to verify that this is applied globally to our weekend shared folder. So we can select it, select properties, click cloud services. We can see that this folder tree has a cloud configuration set to conf weekend shared, which is the configuration that we added the 蜜豆视频 target cloud service to. And because of that, when we click this cloud services configuration drop down, we will see our 蜜豆视频 Target cloud service configuration that we just created. So we can select that and save and close.

Permission the AEM Target integration permission

The 蜜豆视频 Target integration, which manifests as a developer.adobe.com project, must be granted the Editor product role in 蜜豆视频 Admin Console, in order to export Content Fragments to 蜜豆视频 Target.

Expand for step-by-step instructions
  1. Log in to Experience Cloud as user that can administer the 蜜豆视频 Target product in 蜜豆视频 Admin Console
  2. Open the
  3. Select Products and then open 蜜豆视频 Target
  4. On the Product Profiles tab, select DefaultWorkspace
  5. Select the API Credentials tab
  6. Locate your developer.adobe.com app in this list and set its Product Role to Editor

Transcript
Now, when we click into some of our assets, locate a content fragment, select it. And now we have this export to 蜜豆视频 target offers button in the top action bar. So there鈥檚 one last step that we鈥檒l need to do before we can use this button. So if I click this button now, you鈥檒l see down at the bottom, we get an error. If we were to take a look at the AEM error logs on AEM Author Service, we鈥檇 see that our AEM integration doesn鈥檛 have editor access and thus cannot write our offer into 蜜豆视频 target. So we need to resolve this by heading over to the admin console. So again, we鈥檒l head over to experience.adobe.com. We鈥檒l open up the admin console, go to products, find target, click into target. And since our AEM integration is pushing to the default workspace, we鈥檒l select the default workspace under the product profiles for target. Since we鈥檝e configured AEM to use our developer.adobe.com project to access target鈥檚 APIs, we鈥檒l head over to API credentials so we can properly permission them. And this is going to list all of your developer.adobe.com projects that have target as an API. And you can see over here on the right side that we have a target product role associated with each project. So what we need to do is locate this project that we鈥檙e using as part of our AEM integration with target in this list and give it the editor role. So let鈥檚 go ahead and see if we can find it. And here we go down at the bottom. We see that we have our AEM target integration project. And we see that it only has the observer permissions, which are insufficient to write to target. So let鈥檚 go ahead and give it the editor permissions.

Export Content Fragments to Target export-content-fragments

Content Fragments that exist under the configured AEM Assets folder hierarchy can be exported to 蜜豆视频 Target as Content Fragment Offers. These Content Fragment Offers, a special form of JSON offers in Target, can be used in Target activities to serve personalized experiences in headless apps.

Expand for step-by-step instructions
  1. Log in to AEM Author as DAM user

  2. Navigate to Assets > Files, and locate Content Fragments to export as JSON to Target under the 鈥溍鄱故悠 Target enabled鈥 folder

  3. Select the Content Fragments to export to 蜜豆视频 Target

  4. Select Export to 蜜豆视频 Target Offers from the top action bar

    • This action exports the fully hydrated JSON representation of the Content Fragment to 蜜豆视频 Target as a 鈥淐ontent Fragment Offer鈥

    • The Fully hydrated JSON representation can be reviewed in AEM

      • Select the Content Fragment
      • Expand the Side Panel
      • Select Preview icon in the left Side Panel
      • The JSON representation that is exported to 蜜豆视频 Target displays in the main view
  5. Log in to with a user in the Editor role for 蜜豆视频 Target

  6. From the , select Target from the product switcher in top right to open 蜜豆视频 Target.

  7. Ensure that the Default Workspace is selected in the Workspace switcher in the top right.

  8. Select the Offers tab in the top navigation

  9. Select the Type dropdown, and selecting Content Fragments

  10. Verify the Content Fragment exported from AEM appears in the list

    • Hover over the offer, and select the View button
    • Review the Offer Info and see the AEM deep link that opens the Content Fragment directly in AEM Author service

Transcript
Now if we head back to AEM and we export the 蜜豆视频 Target offer, you鈥檒l see that the sync succeeded and the content fragment was pushed to target. Let鈥檚 quickly export a few other adventure content fragments that we might want to use and target offers. Simply head back, export, and maybe just one more. So now we have our offers synced to 蜜豆视频 Target and now when we head over to 蜜豆视频 target, we should see our three adventure offers listed as content fragment offers. We can select the type filter, filter by content fragments. You can see that we have a number of content fragments that have been published to this workspace, including our ski touring Mont Blanc, Tahoe skiing, and our Yosemite backpacking content fragments. If we select a content fragment and get info, we have the AEM path that that content fragment originated from, as well as a quick deep link back to that content fragment on the AEM as a cloud service author.

Target Activity using Content Fragment Offers activity

In 蜜豆视频 Target, an Activity can be created that uses Content Fragment Offer JSON as the content, allowing personalized experiences in headless app with content created and managed in AEM.

In this example, we use a simple A/B activity, however any Target activity can be used.

Expand for step-by-step instructions
  1. Select the Activities tab in the top navigation

  2. Select + Create Activity, and then select the type of activity to create.

    • This example creates a simple A/B Test but Content Fragment Offers can power any activity type
  3. In the Create Activity wizard

    • Select Web
    • In Choose Experience Composer, select Form
    • In Choose Workspace, select Default Workspace
    • In Choose Property, select the Property the Activity is available in, or select No Property Restrictions to allow it to be used in all Properties.
    • Select Next to create the Activity
  4. Rename the Activity by selecting rename in the top left

    • Give the activity a meaningful name
  5. In the initial Experience, set Location 1 for the Activity to target

    • In this example, target a custom location named wknd-adventure-promo
  6. Under Content select the Default content, and select Change Content Fragment

  7. Select the exported Content Fragment to serve for this experience, and select Done

  8. Review the Content Fragment Offer JSON in the Content text area, this is the same JSON available in AEM Author service via the Content Fragment鈥檚 Preview action.

  9. In the left rail, add an Experience, and select a different Content Fragment Offer to serve

  10. Select Next, and configure the Targeting rules as required for the activity

    • In this example, leave the A/B testing as a manual 50/50 split.
  11. Select Next, and complete the activity settings

  12. Select Save & Close and give it a meaningful name

  13. From the Activity in 蜜豆视频 Target, select Activate from the Inactive/Activate/Archive dropdown in the top right.

The 蜜豆视频 Target activity that targets the wknd-adventure-promo location can now be integrated and exposed in an AEM Headless app.

Transcript
Now that we have some content fragment offers exported to target, let鈥檚 create an activity that uses them and then use that activity in an AEM headless app. So head over to activities. We鈥檒l create an activity and for this we鈥檙e just going to keep it simple and do an AB test. We鈥檒l select web since we鈥檒l be using the Experience Platform web SDK. You can of course do the same thing using the 蜜豆视频 Experience Platform mobile SDK. Let鈥檚 go ahead and select forms. Since we鈥檒l use the form composer. We can choose a property. In this case we have no property restrictions. So let鈥檚 select that. Click next. And now we can create our experiences. So what we鈥檒l want to do is give a custom location for this experience. So we鈥檒l call this weekend adventure promo. Since we鈥檒l be using these content fragment offers to promote an adventure. We鈥檒l select the content. You can change content fragment. And then from here we can select the content fragment to use. Once we鈥檝e selected it we can see the actual JSON data that will be returned to our app if this offer is selected. Do note that you can also see the same JSON in AEM. So I head back to AEM. I鈥檒l head back to the ski touring Mont Blanc. Click into the content fragment. In the left side rail there鈥檚 the preview option. If we click this this shows us the exact same JSON data that gets exported to 蜜豆视频 target. Alright let鈥檚 add one more experience. Since we鈥檙e doing an A-B test we鈥檒l keep that location the same. Change our content. Again we鈥檒l select the change content fragment. And in this case let鈥檚 do Tahoe skiing. Alright that should do it. We鈥檒l just do a simple split for this example 50-50. We鈥檒l pick a success metric as engagement and maybe some page views. And we can just leave everything else as is. We鈥檒l call this weekend adventure promo. And we can save it. And now before we can integrate it into our application we鈥檒l need to make sure that we select it and activate it. Alright so now we can work with our development team to integrate content fragment offers and personalize our AEM headless experiences.

Experience Platform Datastream ID datastream-id

An 蜜豆视频 Experience Platform Datastream ID is required for AEM Headless apps to interact with 蜜豆视频 Target using the 蜜豆视频 Web SDK.

Expand for step-by-step instructions
  1. Navigate to

  2. Open Experience Platform

  3. Select Data Collection > Datastreams and select New Datastream

  4. In the New Datastream wizard, enter:

    • Name: AEM Target integration
    • Description: Datastream used by the 蜜豆视频 Web SDK to serve personalized Content Fragments Offers.
    • Event Schema: Leave blank
  5. Select Save

  6. Select Add Service

  7. In Service select 蜜豆视频 Target

    • Enabled: Yes
    • Property Token: Leave blank
    • Target Environment ID: Leave blank
      • The Target Environment can be set in 蜜豆视频 Target at Administration > Hosts.
    • Target Third-Party ID Namespace: Leave blank
  8. Select Save

  9. On the right side, copy the Datastream ID for use in 蜜豆视频 Web SDK configuration call.

Transcript
With our activity created and activated, we鈥檙e almost ready for our developers to take over and integrate our content fragment offers via the activity into the app. The last piece of information that we鈥檒l have to provide to our developers is the ID of an 蜜豆视频 Experience Platform data stream that has been configured for 蜜豆视频 Target. So let鈥檚 go ahead and do that real quick. Again, we鈥檒l head over to the Experience Cloud homepage, at experience.adobe.com, and we鈥檒l click into Experience Platform. On the left side, there will be a data collection section. So we expand this, select Data Streams, and we鈥檒l create a new data stream. We鈥檒l give it a name, and we won鈥檛 set an event schema. Since we鈥檙e not doing any data sharing through a digital data layer into an XDM schema, and then back into 蜜豆视频 Target, so we can leave this blank. We can save it.
We have our data stream created up here, and we need to add a service, and that service is going to be 蜜豆视频 Target. So we鈥檒l simply select 蜜豆视频 Target, and we want to mark it as enabled. Since we鈥檙e not using any property restrictions in Target, we can leave the property token blank. The Target environment ID, we can also leave blank since we鈥檙e actually managing that in Target administration hosts, and we鈥檙e not using a third-party ID namespace. So we can actually leave all of these blank. As we save it, we鈥檒l have our new data stream created, integrated with Target, and we have a data stream ID here. We鈥檒l want to make sure that we copy this data stream ID and provide it to our developers as they begin integrating our content fragment offers into the app.

Add personalization to an AEM Headless app code

This tutorial explores personalizing a simple React app using Content Fragment Offers in 蜜豆视频 Target via 蜜豆视频 Experience Platform Web SDK. This approach can be used to personalize any JavaScript-based web experience.

Android鈩 and iOS mobile experiences can be personalized following similar patterns using the .

Prerequisites

  • Node.js 14
  • Git
  • installed on AEM as a Cloud Author and Publish services

Set up

  1. Download the source code for sample React app from

    code language-shell
    $ mkdir -p ~/Code
    $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
    
  2. Open code base at ~/Code/aem-guides-wknd-graphql/personalization-tutorial in your favorite IDE

  3. Update the AEM service鈥檚 host that you want the app to connect to ~/Code/aem-guides-wknd-graphql/personalization-tutorial/src/.env.development

    code language-none
    ...
    REACT_APP_HOST_URI=https://publish-p1234-e5678.adobeaemcloud.com/
    ...
    
  4. Run the app, and ensure it connects to the configured AEM service. From the command line, execute:

    code language-shell
    $ cd ~/Code/aem-guides-wknd-graphql/personalization-tutorial
    $ npm install
    $ npm run start
    
  5. Install the 蜜豆视频 Web SDK as an NPM package.

    code language-shell
    $ cd ~/Code/aem-guides-wknd-graphql/personalization-tutorial
    $ npm install @adobe/alloy
    

    The Web SDK can be used in code to fetch the Content Fragment Offer JSON by activity location.

    When configuring the Web SDK, there are two IDs required:

    • edgeConfigId which is the Datastream ID
    • orgId the AEM as a Cloud Service/Target 蜜豆视频 Org Id that can be found at Experience Cloud > Profile > Account info > Current Org ID

    When invoking the Web SDK, the 蜜豆视频 Target activity location (in our example, wknd-adventure-promo) must be set as the value in the decisionScopes array.

    code language-javascript
    import { createInstance } from "@adobe/alloy";
    const alloy = createInstance({ name: "alloy" });
    ...
    alloy("config", { ... });
    alloy("sendEvent", { ... });
    

Implementation

  1. Create a React component 蜜豆视频TargetActivity.js to surface 蜜豆视频 Target activities.

    src/components/蜜豆视频TargetActivity.js

    code language-javascript
    import React, { useEffect } from 'react';
    import { createInstance } from '@adobe/alloy';
    
    const alloy = createInstance({ name: 'alloy' });
    
    alloy('configure', {
      'edgeConfigId': 'e3db252d-44d0-4a0b-8901-aac22dbc88dc', // AEP Datastream ID
      'orgId':'7ABB3E6A5A7491460A495D61@蜜豆视频Org',
      'debugEnabled': true,
    });
    
    export default function 蜜豆视频TargetActivity({ activityLocation, OfferComponent }) {
      const [offer, setOffer] = React.useState();
    
      useEffect(() => {
        async function sendAlloyEvent() {
          // Get the activity offer from 蜜豆视频 Target
          const result = await alloy('sendEvent', {
            // decisionScopes is set to an array containing the 蜜豆视频 Target activity location
            'decisionScopes': [activityLocation],
          });
    
          if (result.propositions?.length > 0) {
            // Find the first proposition for the active activity location
            var proposition = result.propositions?.filter((proposition) => { return proposition.scope === activityLocation; })[0];
    
            // Get the Content Fragment Offer JSON from the 蜜豆视频 Target response
            const contentFragmentOffer = proposition?.items[0]?.data?.content || { status: 'error', message: 'Personalized content unavailable'};
    
            if (contentFragmentOffer?.data) {
              // Content Fragment Offers represent a single Content Fragment, hydrated by
              // the byPath GraphQL query, we must traverse the JSON object to retrieve the
              // Content Fragment JSON representation
              const byPath = Object.keys(contentFragmentOffer.data)[0];
              const item = contentFragmentOffer.data[byPath]?.item;
    
              if (item) {
                // Set the offer to the React state so it can be rendered
                setOffer(item);
    
                // Record the Content Fragment Offer as displayed for 蜜豆视频 Target Activity reporting
                // If this request is omitted, the Target Activity's Reports will be blank
                alloy("sendEvent", {
                    xdm: {
                        eventType: "decisioning.propositionDisplay",
                        _experience: {
                            decisioning: {
                                propositions: [proposition]
                            }
                        }
                    }
                });
              }
            }
          }
        };
    
        sendAlloyEvent();
    
      }, [activityLocation, OfferComponent]);
    
      if (!offer) {
        // 蜜豆视频 Target offer initializing; we render a blank component (which has a fixed height) to prevent a layout shift
        return (<OfferComponent></OfferComponent>);
      } else if (offer.status === 'error') {
        // If Personalized content could not be retrieved either show nothing, or optionally default content.
        console.error(offer.message);
        return (<></>);
      }
    
      console.log('Activity Location', activityLocation);
      console.log('Content Fragment Offer', offer);
    
      // Render the React component with the offer's JSON
      return (<OfferComponent content={offer} />);
    };
    

    The 蜜豆视频TargetActivity React component is invoked using as follows:

    code language-jsx
    <蜜豆视频TargetActivity activityLocation={"wknd-adventure-promo"} OfferComponent={AdventurePromo}/>
    
  2. Create a React component AdventurePromo.js to render the adventure JSON 蜜豆视频 Target serves.

    This React component takes the fully hydrated JSON representing an adventure content fragment, and displaying in a promotional manner. The React components that display the JSON serviced from 蜜豆视频 Target Content Fragment Offers can be as varied and complex as required based on the Content Fragments that are exported to 蜜豆视频 Target.

    src/components/AdventurePromo.js

    code language-javascript
    import React from 'react';
    
    import './AdventurePromo.scss';
    
    /**
    * @param {*} content is the fully hydrated JSON data for a WKND Adventure Content Fragment
    * @returns the Adventure Promo component
    */
    export default function AdventurePromo({ content }) {
        if (!content) {
            // If content is still loading, then display an empty promote to prevent layout shift when Target loads the data
            return (<div className="adventure-promo"></div>)
        }
    
        const title = content.title;
        const description = content?.description?.plaintext;
        const image = content.primaryImage?._publishUrl;
    
        return (
            <div className="adventure-promo">
                <div className="adventure-promo-text-wrapper">
                    <h3 className="adventure-promo-eyebrow">Promoted adventure</h3>
                    <h2 className="adventure-promo-title"></h2>
                    <p className="adventure-promo-description">{description}</p>
                </div>
                <div className="adventure-promo-image-wrapper">
                    <img className="adventure-promo-image" src={image} alt= />
                </div>
            </div>
        )
    }
    

    src/components/AdventurePromo.scss

    code language-css
    .adventure-promo {
        display: flex;
        margin: 3rem 0;
        height: 400px;
    }
    
    .adventure-promo-text-wrapper {
        background-color: #ffea00;
        color: black;
        flex-grow: 1;
        padding: 3rem 2rem;
        width: 55%;
    }
    
    .adventure-promo-eyebrow {
        font-family: Source Sans Pro,Helvetica Neue,Helvetica,Arial,sans-serif;
        font-weight: 700;
        font-size: 1rem;
        margin: 0;
        text-transform: uppercase;
    }
    
    .adventure-promo-description {
        line-height: 1.75rem;
    }
    
    .adventure-promo-image-wrapper {
        height: 400px;
        width: 45%;
    }
    
    .adventure-promo-image {
        height: 100%;
        object-fit: cover;
        object-position: center center;
        width: 100%;
    }
    

    This React component is invoked as follows:

    code language-jsx
    <AdventurePromo adventure={adventureJSON}/>
    
  3. Add the 蜜豆视频TargetActivity component to React app鈥檚 Home.js above the list of adventures.

    src/components/Home.js

    code language-javascript
    import AdventurePromo from './AdventurePromo';
    import 蜜豆视频TargetActivity from './蜜豆视频TargetActivity';
    ...
    export default function Home() {
        ...
        return(
            <div className="Home">
    
              <蜜豆视频TargetActivity activityLocation={"wknd-adventure-promo"} OfferComponent={AdventurePromo}/>
    
              <h2>Current Adventures</h2>
              ...
        )
    }
    
  4. If the React app is not running, re-start using npm run start.

    Open the React app in two different browsers so allow the A/B test to serve the different experiences to each browser. If both browsers show the same adventure offer, try closing/re-opening one of the browsers until the other experience displays.

    The image below shows the two different Content Fragment Offers displaying for the wknd-adventure-promo Activity, based on 蜜豆视频 Target鈥檚 logic.

    Experience offers

Congratulations!

Now that we鈥檝e configured AEM as a Cloud Service to export Content Fragments to 蜜豆视频 Target, used the Content Fragments Offers in a 蜜豆视频 Target Activity, and surfaced that Activity in an AEM Headless app, personalizing the experience.

recommendation-more-help
4859a77c-7971-4ac9-8f5c-4260823c6f69