Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Link to internal page w/ relationship field returns too much data

default discord avatar
beautifullittlefoollast year
5

Using Payload 3.0:



I created a field to add links to internal pages:


 {
        name: 'internalHref',
        label: 'Internal URL',
        type: 'relationship',
        relationTo: 'pages'
      }


Each page has a

slug

field that is extracted from this relationship and used for the link.


The issue I'm encountering is that this relationship returns

all

of the page content, not just the slug, and significantly impacts the sites performance.



If I limit the

maxDepth

on the relationship I just get back the ID, is there a way to link directly to the page from that ID, or another way to link to the page w/o returning all of the content from the page?

  • default discord avatar
    hristo6004last year

    If you're not using GraphQL, unfortunately for now I don't think you can get only the specific fields the way you want it. You only get the whole JSON. AFAIK

    @423216344302092288

    was working on a select fields plugin and there was discussions here about such feature in Payload 3, but not sure if there's been anything yet officially.

  • default discord avatar
    ritsu0455last year
  • default discord avatar
    beautifullittlefoollast year

    I accomplished what I needed using field hooks and a hidden field for the true internalHref. It still deals with processing all of the data in the CMS, but performance isn't impacted when using the site because only the shortened slug is returned:



          {
            name: 'internalHref',
            label: 'Internal URL',
            type: 'relationship',
            relationTo: 'pages',
            maxDepth: 0,
            hooks: {
              beforeValidate: [
                async ({ value, req }) => {
                  if (typeof value === 'number') {
                    const pageData = await req.payload.findByID({
                      id: value,
                      locale: 'en-US',
                      collection: 'pages'
                    });
                    return pageData?.id;
                  }
    
                  return value;
                }
              ]
            },
            admin: {
              condition: (_, siblingData) => siblingData.type === 'internal',
              description: 'Route for link'
            }
          },
          {
            name: 'shortenedInternalLInk',
            label: 'Internal Link',
            admin: {
              hidden: true
            },
            type: 'text',
            hooks: {
              beforeValidate: [
                async ({ value, req, siblingData }) => {
                  if (typeof siblingData?.internalHref === 'number') {
                    const pageData = await req.payload.findByID({
                      id: siblingData?.internalHref,
                      locale: 'en-US',
                      collection: 'pages'
                    });
                    return `/${pageData?.slug}`;
                  }
    
                  return value;
                }
              ]
            }
          },
  • default discord avatar
    hristo6004last year

    So you're still doing the computation (fetching the whole document), just not filling the memory with useless data?

  • default discord avatar
    beautifullittlefoollast year

    yep. now the header + footer isn't pulling in all of the block data for every single internally linked page, which was vastly degrading performance when browsing the site.


    its a bit slower publishing the page now because of this hook, but overall performance is much better now.

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.