How to access a referenced document with spa-sdk

Hello,

My question is: how do I use the spa-sdk to get the data from a document referenced by a component. Ideally someone could provide the methods I need to call, and a simple example.

Here is more context on specifically what I’m trying to do.

I created a few document type (product) and a field group (PDPDetail). The PDPDetail references the product type via a field group Link.

Additionally, I created a component using the Site Development(beta) interface. This component uses PDPDetail as its Content type. I’ve placed this component on a page.

In my front-end (next.js) I am getting back the component in the expected container. I can get the content of the component using this line:

const { product: productRef } = getContainerItemContent<WrappedDetailsProps>(component, page) ?? {};

This gets me back product, which is a document reference. It looks like this if I log it:

{ '$ref': '/page/ub8126d0e4049428cbac7abb8bd328226' }

This seems correct, but from here I don’t know how to get the data from this page. I’ve tried the following:

const productDoc = productRef && page?.getContent<Document>(productRef);

This result of logging this is the following:

DocumentImpl {
  model: {
    type: 'document',
    links: { site: [Object] },
    meta: {},
    data: {
      name: a-product-name',
      displayName: 'A Product name',
      localeString: 'en_US',
      contentType: 'referencespa:product',
      id: 'b8126d0e-4049-428c-bac7-abb8bd328226'
    }
  },
  linkFactory: LinkFactory {
    mapping: Map(1) { 'internal' => [Function: bound getSpaUrl] }
  },
  meta: [ comments: [] ]
}

This gets me the document, but I don’t have any of the field values in the document. It makes sense that this would return the document (since that’s what I requested), but I’m not sure what method I should be using. Does anyone have experience with this?

Thanks

Hey Erik, can you share the Delivery API request you’re making for that page?
Ensure the document actually has content on it in the response.

Hey - Thanks for the quick response.

I’m not entirely sure what the Delivery API request is in this case. I’m using the BrPage component from the @bloomreach/react-sdk in the manner that its used in the Next.js example (here). I believe this request to the Delivery API would be handled by the spa-sdk, ultimately.

I can try to dig into the spa-sdk source to find where the request may be if that would help. I can also share the response I’ve gotten for the entire page, or get whatever other information you may want.

With NextJS, the request is going to be made by the server and will be tricky to pull. Instead, just share the environment name you’re using in the .env file and the URL context path you’re requesting. With that you can get the Delivery API response.

For example, https://profserv02.bloomreach.io/delivery/site/v1/channels/us-english/pages/about
This is the Delivery API request for the about page in the us-english channel of the profserv02 namespace.

Thanks again for your response.

Since I’m fairly new to Bloomreach I may not be following your answer here, because of that I hope you can bear with me while I discuss where my head is at.

I’m getting back page data just fine, and reading out the component data for that page. One of these components references another document. For this document I have this object that looks like this { '$ref': '/page/ub8126d0e4049428cbac7abb8bd328226' }. This is where I’m having trouble, as I don’t know how to get the data for this reference. For example, one way I’ve tried is to use the following:

page?.getContent<Document>(productRef)

This gives me back the document, but it doesn’t have the field data (it does have model.data, which contains things like the name of the document, its locale, content type and id).

Are you suggesting that I initiate a manual request for the data referenced by that component, perhaps using a standard fetch instead of a method provided by the spa-sdk? Is there some way I can know how to make the request using the reference I have to the document? Perhaps I have to lookup the document the way I’ve tried, and use its name along with the knowledge of the path that I’m trying to request. Am I on the right track?

Thanks so much and sorry for my inexperience here

Hey erik,

No worries on experience, hope you’re enjoying your time with the CMS!

I’m not suggesting you do anything alternative with the front end code in order to get the document’s content. Ideally, we are only making a single request to the CMS’ Delivery API; any additional requests introduce unnecessary render time. The SDK is performing a request for you to the Delivery API to retrieve all the things you are using through the SDK’s functions. As a troubleshooting step, let’s sidestep the SDK and frontend entirely and make the Delivery API request directly through Postman or browser.

There are limits on the amount of referenced content documents that are returned in the response. I’m curious if the data is actually in the response before we try to retrieve the data through the SDK. That’s why I requested the context path and namespace for the request so that we can review that response for the referenced content document’s document.

Ok, I understand. I was also thinking that it would add too much overhead so happy to be on the same page.

I was able to fetch the document referenced by the component using this request:
https://<subdomain>.bloomreach.io/delivery/site/v1/channels/poc-spa/documents/b8126d0e-4049-428c-bac7-abb8bd328226

And here is the response:

{
  "meta": {
    "product": "brx",
    "version": "1.0",
    "branch": "master"
  },
  "document": {
    "$ref": "/content/ub8126d0e4049428cbac7abb8bd328226"
  },
  "content": {
    "ub8126d0e4049428cbac7abb8bd328226": {
      "type": "document",
      "links": {
        "site": {
          "type": "unknown"
        }
      },
      "meta": {

      },
      "data": {
        "name": "name-changed",
        "displayName": "Name Changed",
        "localeString": "en_US",
        "contentType": "referencespa:product",
        "id": "b8126d0e-4049-428c-bac7-abb8bd328226"
      }
    }
  }
}

It appears this is the document I’m expecting. However, I don’t see the values of the document (I have only given the product content type one field called name, and assigned it an obvious test value (and published it to core). However, this doesn’t appear in this response. The name value that does appear seems to be the name of the document itself (which makes sense - I’d expect the value of the other name to appear somewhere else).

Two more things to check.

  1. Is the content published? The API will only return published content when you are requesting without a token.
  2. Instead of using the documents API (Documents endpoint), use the page API. (Pages endpoint) this is the request that would be made by the SDK, not the documents API.

Thanks for keeping me company here. I’m not expecting you to respond now on account of it being so late (I feel bad as its around midnight my time and I’m not sure where you are).

  1. The content seems to be published, and I’m able to assign it to a component on a page. I can see the green check mark on the document and did remember to go through publishing it. I’m also seeing the document come back (just missing the field in the content type I set up).
  1. Can I use the pages endpoint if the document isn’t stored in the pages folder? I created a product folder as a sibling of pages, since it isn’t a page. I’m trying to use it closer to how (I assume) the banners folder is being used.

There is a chance I haven’t done a good job describing the sort of content type I’m trying to use. In the off chance that it helps, I’ll give it a shot.

The content type I’m referencing would be something akin to the following: you may have a carousel component you want to drop on a page. This component takes slides, and you may want to reuse some of these slides across a number of different pages (and maybe even components). So I figure I would create a document component that represents a slide and then a field group type that allows you to assign slides to it. Then there is a component that uses the field group type as its content type. I can now drop the component on a page, and reference slides I’ve created. I’m able to get the reference to the slides, but not the data in them.

Of course, I’m not making slides and a carousel, but a set of product data that I may want to assign to various components, and each component may represent them differently.

Hello @erik , the issue here is with the property name you have chosen to experiment with

this is a list of all reserved property names you shouldn’t use and name is one of them. As you correctly pointed out there is already a property called name and its causing a conflict with your property being ignored. Kind regards

That would account for it ;D

Well, that’s a mistake I won’t make again.

Thanks for all your patience!