PHPackages                             shel/neos-cross-contentrepository-references - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. shel/neos-cross-contentrepository-references

ActiveNeos-plugin[Utility &amp; Helpers](/categories/utility)

shel/neos-cross-contentrepository-references
============================================

Allows referencing content from other content repositories in the Neos CMS backend

12↑2900%PHPCI passing

Since Jun 22Pushed todayCompare

[ Source](https://github.com/Sebobo/Shel.Neos.CrossContentRepositoryReferences)[ Packagist](https://packagist.org/packages/shel/neos-cross-contentrepository-references)[ RSS](/packages/shel-neos-cross-contentrepository-references/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

Cross Content Repository References for Neos CMS
================================================

[](#cross-content-repository-references-for-neos-cms)

[![Latest Stable Version](https://camo.githubusercontent.com/dd7b9f809ea100bb6a9dbebdf73ea0683b2aac83e5f41997e0f51dd7404e11d4/68747470733a2f2f706f7365722e707567782e6f72672f7368656c2f6e656f732d63726f73732d636f6e74656e747265706f7369746f72792d7265666572656e6365732f762f737461626c65)](https://packagist.org/packages/shel/neos-cross-contentrepository-references)[![Total Downloads](https://camo.githubusercontent.com/64a9f0266c03f21474f219555b9b0fc3eebac93b775218380a1aa63aee58665d/68747470733a2f2f706f7365722e707567782e6f72672f7368656c2f6e656f732d63726f73732d636f6e74656e747265706f7369746f72792d7265666572656e6365732f646f776e6c6f616473)](https://packagist.org/packages/shel/neos-cross-contentrepository-references)[![License](https://camo.githubusercontent.com/a18b0b4a736c61526add85c62e9f3eaa02bc63f135d4d756a99c0201ec3faaf8/68747470733a2f2f706f7365722e707567782e6f72672f7368656c2f6e656f732d63726f73732d636f6e74656e747265706f7369746f72792d7265666572656e6365732f6c6963656e7365)](https://packagist.org/packages/shel/neos-cross-contentrepository-references)

This package for [NeosCMS](https://www.neos.io) makes it possible to reference nodes from **any** content repository via the inspector - not only from the content repository the currently edited node belongs to.

Neos' built-in `reference` and `references` property types are confined to the content repository of the edited node. When a project uses multiple content repositories (e.g. a central "content hub" plus per-site repositories), this package fills the gap by providing a datasource-driven editor and a Fusion helper to resolve the selected nodes again in the frontend.

Features
--------

[](#features)

- `ReferencesDataSource` (`cross-content-repository-references`) — a Neos datasource that lists nodes from an arbitrary content repository for use in the inspector `SelectBoxEditor`.
- The `startingPoint` argument includes the content repository id using the pattern `///`, e.g. `/hub//example-site`.
- Selected nodes are stored as serialized `CrossContentRepositoryReference`JSON strings — one string for a single reference, an array of strings for multiple references. The serialized form contains only the content repository id and node aggregate id; the workspace and dimension space point are resolved from the rendering context (the context node) when the reference is loaded in Fusion.
- `ReferencesHelper` Eel helper (`Shel.Neos.CrossContentRepositoryReferences`) to resolve a node (or a list of nodes) from a serialized `CrossContentRepositoryReference` in Fusion, using a context node for the workspace and dimension.
- `referenceNodesAcrossCR` {@see \\Shel\\Neos\\CrossContentRepositoryReferences\\FlowQueryOperations\\ReferenceNodesAcrossCROperation FlowQuery operation} that reads cross-CR references from a node property and replaces the FlowQuery context with the resolved nodes: `${q(node).referenceNodesAcrossCR("propertyName")}`.

Installation
------------

[](#installation)

Run this in your site package:

```
composer require --no-update shel/neos-cross-contentrepository-references

```

Then run `composer update` in your project root.

Usage
-----

[](#usage)

### Configure a property

[](#configure-a-property)

The package ships 2 node type presets `crossContentRepositoryReference` and `crossContentRepositoryReferences`. You can use them to configure a property of any node type:

```
'Your.Package:NodeType':
  properties:
    myCrossReference:
      options:
        preset: 'crossContentRepositoryReference'
      ui:
        label: 'My reference'
        inspector:
          editorOptions:
            placeholder: 'Select a node'
            dataSourceAdditionalData:
              startingPoint: '/default//neos-demo'
              nodeTypes: ['Neos.Neos:Document']
```

### `startingPoint` format

[](#startingpoint-format)

The `startingPoint` is **not** relative to the currently edited content repository as in Neos' default behaviour. Instead it contains the content repository id as its first segment:

```
///

```

Examples:

- `/default//my-site` — the `my-site` site in the `default` CR
- `/hub//content-hub` — the `content-hub` site in the `hub` CR

### Available `dataSourceAdditionalData` options

[](#available-datasourceadditionaldata-options)

OptionRequiredDefaultDescription`startingPoint`yes-`///``nodeTypes`no`Neos.Neos:Document`Node type names, e.g. \[`Neos.Neos:Document`, Foo.Bar:Baz\]`dimensionValues`noedited node's dimension space pointJSON object, e.g. `{"language":"de"}``searchTerm`no-Fulltext search term to pre-filter results### Resolving selected nodes in Fusion

[](#resolving-selected-nodes-in-fusion)

Selected values are stored as serialized `CrossContentRepositoryReference`JSON strings (containing only `contentRepositoryId` and `nodeAggregateId`). Resolve them in Fusion via the registered Eel helper `Shel.Neos.CrossContentRepositoryReferences.Node`, passing the context node (whose workspace and dimension space point are used to load the referenced node) and the serialized reference:

```
prototype(Your.Package:NodeType) < prototype(Neos.Neos:ContentComponent) {
    # Single reference (property "crossReference" holds a JSON string)
    referenceNode = ${Shel.Neos.CrossContentRepositoryReferences.node(node, node.properties.crossReference)}

    # Multiple references (property "crossReferences" holds an array of JSON strings)
    referenceNodes = ${Shel.Neos.CrossContentRepositoryReferences.nodes(node, node.properties.crossReferences)}

    # Render the referenced nodes
    renderer = Neos.Fusion:Loop {
        items = ${props.referenceNodes}
        itemName = 'referencedNode'
        itemRenderer = Neos.Neos:ContentCase {
            node = ${referencedNode}
        }
    }

    @cache {
        mode = 'cached'
        entryTags {
            # Flush the cache for this node when the referenced nodes change
            references = ${Neos.Caching.nodeTag(Shel.Neos.CrossContentRepositoryReferences.nodes(node, node.properties.crossReferences))}
        }
    }
}

```

The helper returns `Neos\ContentRepository\Core\Projection\ContentGraph\Node`instances (or `null` / a filtered array if a node could not be resolved), so you can use them like any other node - including `q(node)` FlowQuery operations (note: FlowQuery operates within the referenced node's content repository).

### Using the `referenceNodesAcrossCR` FlowQuery operation

[](#using-the-referencenodesacrosscr-flowquery-operation)

The package also provides a dedicated FlowQuery operation that reads the cross-CR references from a node property and replaces the context with the resolved nodes, enabling further chaining:

```
prototype(Your.Package:NodeType) < prototype(Neos.Neos:ContentComponent) {
    # The operation reads the property "crossReferences" from the current node,
    # resolves the stored cross-CR references, and sets the resolved nodes
    # as the FlowQuery context.
    items = ${q(node).referenceNodesAcrossCR('crossReferences')}

    # Now iterate over the resolved nodes and render them
    renderer = Neos.Fusion:Loop {
        items = ${props.items}
        itemName = 'referencedNode'
        itemRenderer = Neos.Neos:ContentCase {
            node = ${referencedNode}
        }
    }

    # Further chaining works as usual
    titles = ${q(node).referenceNodesAcrossCR('crossReferences').property('title')}

    @cache {
        mode = 'cached'
        entryTags {
            references = ${Neos.Caching.nodeTag(q(node).referenceNodesAcrossCR('crossReferences'))}
        }
    }
}

```

Single and multiple references are both supported: if the property contains a single JSON string, one node is resolved; if it contains an array of strings, all referenced nodes are resolved. Unresolvable entries are silently skipped.

How it works
------------

[](#how-it-works)

1. `ReferencesDataSource::getData()` parses `startingPoint` into a `ContentRepositoryId` and an `AbsoluteNodePath`, fetches a subgraph for the resolved content repository, workspace and dimension space point, and finds the start node via `findNodeByAbsolutePath()`.
2. It lists descendants using `ContentSubgraphInterface::findDescendantNodes()` with a `NodeTypeCriteria`filter and an optional `SearchTerm`.
3. Each result is mapped to `{label, value, nodeType}` where `value` is `CrossContentRepositoryReference::fromNode($node)->toJson()` — containing only the content repository id and node aggregate id. This is what gets stored on the property.
4. In Fusion, `NodeHelper::node()` deserializes the `CrossContentRepositoryReference`, fetches the matching content repository and a subgraph using the **context node's** workspace and dimension space point, and resolves the node via `findNodeById()`.

Contributions
-------------

[](#contributions)

Contributions are very welcome! Please create detailed issues and PRs.

**If you use this package and want to support or speed up its development, [get in touch with me](mailto:me@helzle.it).**

License
-------

[](#license)

See [License](./LICENSE.txt)

###  Health Score

22

—

LowBetter than 21% of packages

Maintenance65

Regular maintenance activity

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/5c9f106db319e8698dcb4aedfe8034f0442d379ebbd78fcd67b884999b2236f1?d=identicon)[Sebobo](/maintainers/Sebobo)

---

Top Contributors

[![Sebobo](https://avatars.githubusercontent.com/u/596967?v=4)](https://github.com/Sebobo "Sebobo (4 commits)")

---

Tags

contentrepositoryneoscms

### Embed Badge

![Health badge](/badges/shel-neos-cross-contentrepository-references/health.svg)

```
[![Health](https://phpackages.com/badges/shel-neos-cross-contentrepository-references/health.svg)](https://phpackages.com/packages/shel-neos-cross-contentrepository-references)
```

###  Alternatives

[spatie/lighthouse-php

Run Google Lighthouse using PHP

26957.1k2](/packages/spatie-lighthouse-php)[shyim/danger-php

Port of danger to PHP

8553.4k](/packages/shyim-danger-php)[fishpig/magento2-wordpress-integration-yoastseo

Magento 2 WordPress Inegration Addon module to support the WordPress SEO plugin by Yoast.

18198.8k](/packages/fishpig-magento2-wordpress-integration-yoastseo)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
