`<RichText />` links are returning “Cannot read property \‘target\’ of undefined”

<RichText /> links are returning “Cannot read property \‘target\’ of undefined”.

We tried to fix this with a custom serializer :

  const myCustomLink = (type, element, content, children, index, document) => (
    <a href={element.data.url} target={element.data.target}>
      {content}
    </a>
  )

<RichText render={item.bodyRichText} serializeHyperlink={myCustomLink} />

But data is empty… can you give us a little help here please?

Custom serialisers only have 4 arguments -

function htmlSerialiser (type, element, content, children) {
  if (type === 'hyperlink') {
    return (
      <a href={PrismicDOM.Link.url(element.data, linkResolver)}>
        {content}
      </a>
    )
  } else {
    return null
  }
}

That error sounds like you aren’t passing in the right value into the link, however. Can you console.log the page data, and what you are passing in to the <RichText /> component?

[ { text:
     'Perante o custo elevado que o mercado de arrendamento apresenta atualmente, muitas famílias portuguesas enfrentam dificuldades em arrendar uma habitação. Para dar resposta a esta necessidade, o Governo desenvolveu o Programa de Arrendamento Acessível (PAA) que visa aumentar a oferta habitacional para arrendamento com valores até 20% mais baixos face aos preços praticados no mercado, contribuindo para que estes sejam mais ajustados aos rendimentos das famílias.',
    type: 'paragraph',
    spans: [ [Object], [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text: ' ',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'Assim, o Governo aprovou o Decreto-lei n.º 68/2019, de 22 de Maio, que cria o PAA, tendo entrado em vigor a 1 de Julho.',
    type: 'paragraph',
    spans: [ [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text: '',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text: 'Quem pode aceder?',
    type: 'heading3',
    spans: [ [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text: '',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'O PAA é de adesão voluntária e destina-se a senhorios e inquilinos que pretendem iniciar um novo contrato de arrendamento ou renovar um já decorrente.',
    type: 'paragraph',
    spans: [ [Object], [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text: '',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text: 'Senhorios',
    type: 'heading5',
    spans: [ [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'Qualquer pessoa singular ou coletiva, pública ou privada, pode colocar alojamentos que cumpram os requisitos mínimos de segurança e conforto para arrendamento no âmbito do PAA.',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'Os senhorios que colocam os seus imóveis no programa com rendas reduzidas estão sujeitos a benefícios fiscais, ficando assim isentos pagar o valor de IRS ou IRC sobre as rendas.',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'Para fazer a simulação das condições sob as quais o senhorio pode arrendar o seu imóvel, basta aceder ao Portal da Habitação e preencher o Simulador de Rendas - Prestador com as informações sobre a habitação.',
    type: 'paragraph',
    spans: [ [Object], [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text: '',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text: 'Arrendatários ',
    type: 'heading4',
    spans: [ [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'Qualquer pessoa ou conjunto de pessoas podem arrendar um alojamento no âmbito do PAA, desde que o total do seu rendimento anual bruto seja inferior a 35 000 euros brutos anuais no caso de tratar-se de uma pessoa sozinha, e 45 000 euros no caso de se tratar de um agregado habitacional de duas pessoas. Por cada inquilino extra são somados 5 mil euros brutos aos 45 mil euros anuais. A renda deverá representar 15 a 35% do rendimento médio mensal.',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'Os inquilinos podem também fazer uma simulação online no Simulador de Renda-Candidato disponibilizado no Portal da Habitação.',
    type: 'paragraph',
    spans: [ [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'Todos os seus elementos, incluindo os menores ou dependentes contam para a dimensão do agregado familiar.',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'Os estudantes ou as pessoas inscritas em cursos de formação profissional podem ser candidatos, mesmo que não possuam rendimentos próprios, desde que o pagamento da renda seja assegurado por um fiador. Nesta situação é necessário indicar o concelho do domicílio fiscal, os dados do fiador, o comprovativo de inscrição na universidade e a declaração de fiança.',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text: '',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text: 'Como se inscrever?',
    type: 'heading3',
    spans: [ [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text: '',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text: 'Senhorios',
    type: 'heading4',
    spans: [ [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'Os proprietários do alojamento inscrevem-se na Plataforma do Arrendamento Acessível, preenchem a ficha de alojamento e submetem os documentos instrutórios (Certificado Energético e Caderneta Predial).',
    type: 'paragraph',
    spans: [ [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text: '',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text: 'Arrendatários',
    type: 'heading4',
    spans: [ [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'Os inquilinos registam a sua candidatura na Plataforma do Arrendamento Acessível, preenchem o formulário e submetem os documentos instrutórios (Comprovativos de rendimentos e declaração de fiador no caso de estudantes). Deve preencher a candidatura com os dados referentes às características do agregado (dimensão e rendimentos), bem como ao tipo de alojamento que procura.',
    type: 'paragraph',
    spans: [ [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text: '',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text: 'Quais as condições de Habitação?',
    type: 'heading3',
    spans: [ [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text: '',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'No PAA exige-se apenas uma ocupação mínima das habitações, isto é, uma pessoa por quarto, por exemplo, um agregado composto por um casal com um filho pode arrendar no máximo um T3.',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'Os contratos de arrendamento no âmbito do PAA têm um prazo mínimo de 5 anos. Caso se trate de uma habitação para residência temporária de estudantes do ensino superior deslocados, o prazo mínimo é de 9 meses. ',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'Segundo os critérios do PAA, o valor das rendas é calculado com base no Valor de Referência de Arrendamento (VRA) e tem de ser, pelo menos, 20% face aos preços de mercado.',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text: '',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text: 'Que seguros são exigidos?',
    type: 'heading3',
    spans: [ [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text: '',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'Para garantir a maior segurança e estabilidade nos contratos de arrendamento do PAA, o Governo aprovou o Decreto-Lei n.º 69/2019, de 22 de maio, que estabelece o regime dos seguros obrigatórios de arrendamento acessível.',
    type: 'paragraph',
    spans: [ [Object] ],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'No Programa de Arrendamento Acessível é obrigatória a contratação de seguros com as garantias de indemnização por falta de pagamento de renda (a contratar pelo senhorio), indemnização por quebra involuntária de rendimentos (a contratar pelos arrendatários) e indemnização por danos no imóvel(a contratar pelos arrendatários).',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text:
     'No caso do arrendamento do imóvel ser feito a estudantes ou formandos dependentes não existe obrigação da contratação de seguros por parte dos inquilinos ou do senhorio.',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null },
  { text: '',
    type: 'paragraph',
    spans: [],
    dimensions: null,
    url: null,
    alt: null } ]
{ service: 'service-frontera',
  when: '2020-05-19T16:14:37.105Z',
  level: 'ERROR',
  environment: 'STG',
  message:
   'Cannot read property \'target\' of undefined\nTypeError: Cannot read property \'target\' of undefined\n    at serializeHyperlink (/Users/paulo.alegria/Sites/service-frontera/node_modules/prismic-reactjs/dist/prismic-reactjs.js:2473:33)\n    at serialize (/Users/paulo.alegria/Sites/service-frontera/node_modules/prismic-reactjs/dist/prismic-reactjs.js:2437:14)\n    at e (/Users/paulo.alegria/Sites/service-frontera/node_modules/prismic-reactjs/dist/prismic-reactjs.js:1084:25)\n    at /Users/paulo.alegria/Sites/service-frontera/node_modules/prismic-reactjs/dist/prismic-reactjs.js:1081:32\n    at Array.reduce (<anonymous>:null:null)\n    at e (/Users/paulo.alegria/Sites/service-frontera/node_modules/prismic-reactjs/dist/prismic-reactjs.js:1080:32)\n    at /Users/paulo.alegria/Sites/service-frontera/node_modules/prismic-reactjs/dist/prismic-reactjs.js:1085:12\n    at /Users/paulo.alegria/Sites/service-frontera/node_modules/prismic-reactjs/dist/prismic-reactjs.js:1086:10\n    at Array.map (<anonymous>:null:null)\n    at Object.u [as serialize] (/Users/paulo.alegria/Sites/service-frontera/node_modules/prismic-reactjs/dist/prismic-reactjs.js:1076:49)\n    at renderRichText (/Users/paulo.alegria/Sites/service-frontera/node_modules/prismic-reactjs/dist/prismic-reactjs.js:2568:84)\n    at RichText (/Users/paulo.alegria/Sites/service-frontera/node_modules/prismic-reactjs/dist/prismic-reactjs.js:2231:83)\n    at processChild (/Users/paulo.alegria/Sites/service-frontera/node_modules/react-dom/cjs/react-dom-server.node.development.js:2888:14)\n    at resolve (/Users/paulo.alegria/Sites/service-frontera/node_modules/react-dom/cjs/react-dom-server.node.development.js:2812:5)\n    at ReactDOMServerRenderer.render (/Users/paulo.alegria/Sites/service-frontera/node_modules/react-dom/cjs/react-dom-server.node.development.js:3202:22)\n    at ReactDOMServerRenderer.read (/Users/paulo.alegria/Sites/service-frontera/node_modules/react-dom/cjs/react-dom-server.node.development.js:3161:29)\n    at renderToString (/Users/paulo.alegria/Sites/service-frontera/node_modules/react-dom/cjs/react-dom-server.node.development.js:3646:27)\n    at /Users/paulo.alegria/Sites/service-frontera/build/build-imovirtualpt/server.js:33619:95\n    at TransactionShim.applySegment (/Users/paulo.alegria/Sites/service-frontera/node_modules/newrelic/lib/shim/shim.js:1424:20)\n    at _applyRecorderSegment (/Users/paulo.alegria/Sites/service-frontera/node_modules/newrelic/lib/shim/shim.js:1015:20)\n    at _doRecord (/Users/paulo.alegria/Sites/service-frontera/node_modules/newrelic/lib/shim/shim.js:994:17)\n    at wrapper (/Users/paulo.alegria/Sites/service-frontera/node_modules/newrelic/lib/shim/shim.js:965:24)\n    at API.

How are you fetching the data? It’s odd, because the error is coming from this line in prismic-reactjs, and that is reading the data from the spans you see there.

You could pass in a custom link handler like this (which doesn’t have functionality for opening in a new tab):

function serializeHyperlink(linkResolver, element, children, key) {
  const props = { href: LinkHelper.url(element.data, linkResolver) }
  return createElement('a', propsWithUniqueKey(props, key), children)
}