9gustin / react-notion-render

A library to render notion pages
MIT License
142 stars 20 forks source link

Add Ability to Customize rel and target Attributes in Link Elements, with blockComponentsMapper Support #183

Open nublson opened 1 month ago

nublson commented 1 month ago

Summary: Currently, all links in my Notion-rendered pages are automatically set with rel="noreferrer" and target="_blank", and I cannot customize this behavior. This affects both internal and external links, limiting control over SEO, tracking, security, and user experience. I suggest allowing customization of both the rel and target attributes, along with adding support to customize link elements using the blockComponentsMapper feature, similar to how image components are mapped.

Problem:

  1. Internal Links:
  1. External Links:

Proposed Solution:

  1. Allow Customization of rel and target Attributes:
  1. Custom Link Mapping Using blockComponentsMapper:

Example Implementation:

<Render
  blocks={blocks}
  simpleTitles
  classNames
  blockComponentsMapper={{
    image: ImageBlock,
    link: LinkBlock,  // Custom link handling
  }}
/>

Desired Link Behavior:

<a href="/internal-page" target="_self" rel="">Internal Link (same tab)</a>
<a href="https://www.example.com" target="_blank" rel="noopener noreferrer">External Link (new tab)</a>

Benefits:

Steps to Reproduce:

  1. Add links to Notion-rendered pages, which are currently automatically set with target="_blank" and rel="noreferrer".
  2. Observe that there is no way to customize these attributes or control whether links open in a new tab.
  3. Users cannot customize the link rendering behavior, unlike image blocks.
nublson commented 1 month ago

Okay, since you seem to be offline, I decided to "try" adding this feature because I really need it, what I did was add a new property to the Render component called linkAttributes. This property is a function that receives one argument (the link) and returns an object with the respective target and rel attributes.

Something like that:

<Render
    blocks={blocks}
    blockComponentsMapper={myMapper}
    emptyBlocks
    classNames
    useStyles
    linkAttributes={(url) => {
      console.log({ url })
      return {
        target: 'my custom target',
        rel: 'my custom rel'
      }
    }}
/>

It will be very useful for the case you need to handle the internal and external links separately.

<Render
    blocks={blocks}
    simpleTitles
    classNames
    blockComponentsMapper={{
      image: ImageBlock,
    }}
    linkAttributes={(link) => {
      const isInternalLink =
        link.startsWith(process.env.BASE_URL) || link.startsWith("/");

      if (isInternalLink) {
        return {
          target: "_self",
        };
      }

      return {
        target: "_blank",
        rel: "noopener noreferrer",
      };
    }}
/>

I will push the pull request, hope you like it and also hope it helps the other ones who love your library like me! ❤️

nublson commented 1 month ago

Okay, I just decided to install my pull request version on my project and move to prod! It's working fine!

Heres an example: https://nublson.com/blog/how-to-create-a-daily-routine-that-boosts-productivity-and-well-being