Skip to content

[Feature Request] Remote Components #220

@CaarLo1337

Description

@CaarLo1337

Hi,

we noticed that currently there doesn’t seem to be support for resolving remote section through the package – from what we've seen, only remote images are handled in this way. However, resolving remote section is a common use case in CMS-driven setups, and we believe it could also benefit others.

We’ve implemented a workaround via a fork, which temporarily solves our issue – but this is merely a transitional solution. Ideally, this feature could be handled similarly to how remote images or pageRefs are resolved, using proper ID references.

Additionally, we noticed in the README that remotes are only defined with a single language context. This doesn’t reflect our use case: we use Next.js as a backend-for-frontend (BFF), and in our setup, the remote API is re-instantiated with every request. This allows us to dynamically pass a locale per API call.

FirstSpirit Component

<FS_REFERENCE name="st_referenceSection" sections="yes">
    <LANGINFOS>
      <LANGINFO lang="*" label="Section"/>
    </LANGINFOS>
    <PROJECTS>
      <REMOTE name="master">
        <SOURCES>
          <FOLDER name="root" store="sitestore"/>
        </SOURCES>
      </REMOTE>
    </PROJECTS>
  </FS_REFERENCE>

CaaSMapper.ts

      case 'FS_REFERENCE':
        if (!entry.value) return null
        if (entry.value.fsType === 'Media') {
          return this.registerReferencedItem(
            entry.value.identifier,
            path,
            entry.value.remoteProject || remoteProjectId
          )
        } else if (['PageRef', 'GCAPage'].includes(entry.value.fsType)) {
          const reference: Reference = {
            type: 'Reference',
            referenceId: entry.value.identifier,
            referenceRemoteProject:
              entry.value.remoteProject || remoteProjectId,
            referenceType: entry.value.fsType,
          }
          // NEW register section
          Object.keys(entry.value).includes('section') &&
            Object.assign(reference, {
              sectionId: entry.value.section?.identifier,
              section: this.registerReferencedItem(
                entry.value.identifier,
                path,
                entry.value.remoteProject || remoteProjectId
              ),
            })
          return reference
        }
        return entry

MappingUtils.ts

const denormalizeResolvedReferences = (
  mappedItems: (CaasApi_Item | MappedCaasItem)[],
  referenceMap: ReferencedItemsInfo,
  resolvedReferences: ResolvedReferencesInfo,
  remoteProjectId?: string,
  logger?: Logger
) => {
  if (!referenceMap || Object.keys(referenceMap).length === 0)
    return mappedItems
  // denormalize
  for (const [referencedId, occurences] of Object.entries(referenceMap)) {
    // Iterate over all insertion paths and insert references into objects
    occurences.forEach((path) => {
      if (resolvedReferences[referencedId]) {
        const resolvedImage = imageMapForceResolution({
          resolvedReferences,
          path,
          referencedId,
        })
        // NEW resolve section
        if (
          get(resolvedReferences, path) &&
          get(resolvedReferences, [...path, 'sectionId'])
        ) {
          const sectionId = get(resolvedReferences, [...path, 'sectionId'])
          const pageObject = resolvedReferences[referencedId] as Page
          set(
            resolvedReferences,
            path,
            find(
              pageObject.children.flatMap((child) => child.children),
              (section) => (section as Section).id === sectionId
            )
          )
        } else {
          set(
            resolvedReferences,
            path,
            resolvedImage || resolvedReferences[referencedId]
          )
        }
      } else {
        logger?.warn(
          `[denormalizeResolvedReferences] Unable to find object [${referencedId}] during denormalization for path [${path}].`
        )
      }
    })
  }

  // update mappedItems
  const queriedIds = mappedItems
    .filter((item) => !!item)
    .map((item) => getItemId(item, remoteProjectId))

  return findResolvedReferencesByIds(queriedIds, resolvedReferences)
}

We’d really appreciate if you could consider these use cases in a future update.

Thanks again and best regards!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions