Footer Exception and Missing Pages: Debugging Cache and Configuration Issues

Hi everyone,

I’m currently building a project based on the Neos Demo and have encountered two issues that seem related. I’m struggling to debug and would appreciate your guidance.

1. Issue with the Global Footer and Missing ContentCollection

I’m getting the following exception:

Exception #1389352984: No content collection of type Neos.Neos:ContentCollection could be found in the current node (/sites/my-vendor/node-kxsfrha8v9c0t) or at the path "footer". You might want to adjust your node type configuration and create the missing child node through the "./flow node:repair --node-type my.Vendor:Document.Page" command.

Here’s my current setup:

  • The Homepage.yaml is structured like this example: Homepage.yaml

  • Similarly, my Page.yaml follows this structure: Page.yaml

Only for the Homepage.yaml, the footer is defined as a child node.

For the footer, I’m using the integration code from the Neos Demo: Footer Integration.

I’ve added some tiny adjustments (experiments with caching…), as shown below:

prototype(my.Vendor:Integration.Footer) < prototype(Neos.Fusion:Renderer) {
    renderPath = '/footer'
}

prototype(my.Vendor:Integration.Footer.Renderer) < prototype(my.Vendor:Presentation.Footer) {

    content = Neos.Neos:ContentCollection {
        nodePath = ${q(site).children('footer').property('_path')}
        attributes.class = 'content'
    }
    copyright = ${q(node).children('footer').property('title')}

    @cache {
        mode = 'cached'
        entryIdentifier {
            static = 'footer'
            site = ${site}
        }
        entryTags {
            1 = ${Neos.Caching.nodeTag(documentNode)}
            2 = ${Neos.Caching.nodeTag(q(documentNode).parents())}
            3 = ${Neos.Caching.nodeTypeTag('my.Vendor:Collection.Content.Footer')}
        }
    }
}

footer = my.Vendor:Integration.Footer.Renderer

For the presentation part, I used this structure: Footer Presentation

prototype(my.Vendor:Presentation.Footer) < prototype(Neos.Fusion:Component) {
    renderer = afx`
        <footer>
            <Neos.Neos:ContentCollection nodePath="footer" />
        </footer>
    `
}

Initially, I tried adding more components to the footer (e.g., <my.Vendor:Presentation.Footer.Provider {...props}) but encountered issues passing properties. As a workaround, I’m now using <Neos.Neos:ContentCollection nodePath="footer" />.

Despite that, the exception persists, and I’m unsure what’s missing.

2. New Pages Not Displayed in the Frontend

I’ve also encountered issues with newly created pages (my.Vendor:Document.Page). Here’s what happens:

  1. In the backend:
  • I can create pages, edit their content, and navigate to them without any issues.
  1. In the frontend:
  • The new pages are not visible in the navigation.
  • Trying to preview or directly access these pages results in the same exception as in Issue 1.
  1. Cache behavior:
  • If I flush the cache using flow:cache:flush, the pages become visible and accessible in the frontend.
  • However, after flushing, the backend sometimes throws the same exception as in Issue 1. Strangely, after navigating to the homepage in the backend, all pages load correctly without errors.
  1. Browser-specific behavior:
  • If I switch to a different browser (e.g., Edge), the homepage navigation again shows no pages. However, directly accessing the new pages via URL works (If already flushed or it was working already in Chrome).

This leads me to suspect a caching issue. I’m using Redis for caching with this configuration: Redis Configuration.

What I’ve Tried

  • Reviewing my node type configuration (Homepage.yaml, Page.yaml).
  • Experimenting with caching.
  • Manually repairing nodes with ./flow node:repair.
  • Flushing the cache, which temporarily resolves the issue but is not a viable solution.

Suspicions and Open Questions

  • Could this be a caching misconfiguration (e.g., incorrect tagging or Redis behavior)?
  • Are my node definitions or Fusion components missing something?
  • Why do nodes sometimes seem to lose their parent relationship?
  • I’d greatly appreciate any tips or ideas for debugging this issue further.

Thanks in advance for your help! :slight_smile:

1 Like

You should use the provided prop “content” in your presentation component instead of creating a new ContentCollection there, which will try to find children on the current document node.

Also you need to use “site” in the cache configuration instead of the “documentNode”.

Then it should basically work but could be cleanup up a bit further. But first try to get it working.

2 Likes

Thanks a lot @sebobo! That actually works perfectly fine :smiling_face:

I now have it like the following, but as you said, probably some redundancy can be removed regarding the entryTags:

prototype(my.Vendor:Integration.Footer) < prototype(Neos.Fusion:Renderer) {
    renderPath = '/footer'
}

prototype(my.Vendor:Integration.Footer.Renderer) < prototype(my.Vendor:Presentation.Footer) {

    content = Neos.Neos:ContentCollection {
        nodePath = ${q(site).children('footer').property('_path')}
        attributes.class = 'content'
    }
    copyright = ${q(node).children('footer').property('title')}

    @cache {
        mode = 'cached'
        entryIdentifier {
            static = 'footer'
            site = ${site}
        }
        entryTags {
			1 = ${Neos.Caching.nodeTag(site)}
			2 = ${Neos.Caching.nodeTag(q(site).parents())}
        }
    }
}
footer = my.Vendor:Integration.Footer.Renderer
prototype(my.Vendor:Presentation.Footer) < prototype(Neos.Fusion:Component) {

    renderer = afx`
        <footer>
			{props.content}
        </footer>
    `
}

In the same breath, i’ve also cleaned/changed the header component - which i haven’t mentioned yet (it is also based on the Neos.Demo)

prototype(my.Vendor:Integration.Header) < prototype(Neos.Fusion:Renderer) {
    renderPath = '/header'
}

prototype(my.Vendor:Integration.Header.Renderer) < prototype(my.Vendor:Presentation.Header) {
    homeUri = Neos.Neos:NodeUri {
        node = ${site}
    }

    menuItems = Neos.Neos:MenuItems {
        maximumLevels = 6
    }

    renderer.@process.convertUris = Neos.Neos:ConvertUris {
        forceConversion = true
    }

    @cache {
        mode = 'cached'
        entryIdentifier {
            static = 'header'
            site = ${site}
        }
        entryTags {
            1 = ${Neos.Caching.nodeTag(site)}
            2 = ${Neos.Caching.nodeTag(q(site).children())}
            3 = ${Neos.Caching.nodeTypeTag('Neos.Neos:Document', site)}
        }
    }
}

header = my.Vendor:Integration.Header.Renderer

However, now as i set up the cache for the header that way, it seems that there is a confusion about the active navigation element. I basically set the active attribute like that:

prototype(my.Vendor:Presentation.Header.Desktop.Component.Atom.ShortcutExternal.NavigationItem) < prototype(Neos.Fusion:Component) {
    # item from Neos.Neos:MenuItems
    item = null	

    renderer = afx`
		<Neos.Neos:NodeLink
			@if.render={!(item.subItems)}
			@if.has={${q(item.node).is('[instanceof Neos.Neos:Shortcut]')}}
			tagName="navigation-item" 
			node={item.node}
			attributes.urlPath={item.node.properties.uriPathSegment}
			attributes.active={(item.state == 'current' || item.state == 'active') ? true : false}
			attributes.label={item.label}
		>
				{item.label}
		</Neos.Neos:NodeLink>
    `
}

I suppose it is also caching related, as currently always the first parent (my.Vendor:Document.Page) page of the homepage (my.Vendor:Document.Homepage) is having the active attribute. When i’m navigating from page to page, this doesn’t change (sticky). Using flow:cache:flush resolves that, but then there is no active item at all anymore.

<navigation-item href="/test" urlpath="test" active="" label="Seite 1" class="wb-header-navigation-item hydrated">Seite 1</navigation-item>

It is possible to fully remove the @cache { } configuration from my.Vendor:Integration.Header and it is working without any issues. But i’m not sure if that’s the recommended way :slight_smile:

You can remove the “2 = ${Neos.Caching.nodeTag(q(site).parents())}” from both configs as it doesn’t do anything.

If you use an active state in Fusion for the header the global caching doesn’t really work as you need a separate cache entry for each site to contain the active state.
So you can either give up the global cache for all pages and add the documentNode to the entryIdentifiers and lose some performance, or you set the active state in JavaScript or with some other workaround, so that again all pages can share the same header.
I usually go the second way so I can keep the performance benefit.

1 Like

Thanks a lot for that insight! I was not aware of the issue and i’ll now consider trying to get the active state using JavaScript anyhow, as performance is more important to me :slight_smile: