TypeCellOS / BlockNote

A React Rich Text Editor that's block-based (Notion style) and extensible. Built on top of Prosemirror and Tiptap.
https://www.blocknotejs.org/
Mozilla Public License 2.0
5.91k stars 386 forks source link

How can I keep links from opening in a new tab #764

Closed EvanParden closed 1 month ago

EvanParden commented 1 month ago

I am building an application similar to Obsidian, where there are internal and external links. I have tried to modify them. I have special links for the internal links that start with a $ and then an ID, for example: $55a2902f... For these links, I do not want to open them in a new tab, so I have tried to remove previous event listeners and then handle it with a function. This works, but it still opens a new blank tab even though all attributes are removed. I inspected it with dev tools and everything is removed, and my code works, but it is still opening a new tab with auto:blank.

Disabling special links

  function disableSpecialLinks(): void {
    // Get all <a> elements on the page
    const links = document.querySelectorAll<HTMLAnchorElement>('a');

    // Iterate over each link
    links.forEach(link => {
        const href = link.getAttribute("href");
        if (href && !href.startsWith("$")) {
            // Remove previous event listeners
            const oldOnClick = link.onclick;
            if (oldOnClick) {
                link.removeEventListener("click", oldOnClick);
            }

            // Add event listener
            link.addEventListener("click", (event) => {
                event.preventDefault();
                event.stopPropagation();

                console.log(link.getAttribute("data-href"));
            });

            // Set new attributes
            link.setAttribute("href", "javascript:void(0)");
            link.setAttribute("data-href", href);
            link.removeAttribute("target"); // Remove target to prevent opening in new tab
        }
    });
}

Special link output

<a href="javascript:void(0)" data-href="$55a2902f-ceae-4d23-bd24-dd1d2812f78e">test</a>

Normal link output

<a target="_blank" rel="noopener noreferrer nofollow" href="https://www.exsample.com">test</a>

I have also tried adding or modifying the _tiptap editor extensions but no luck

I know that this is not a future request but i have been stuck on this for a while now and i ask on Discord but have not gotten any answers, Any help would be greatly appreciated Thanks!

YousefED commented 1 month ago

Hi @EvanParden,

The best way to do this would be to remove Link from the tiptap extensions (https://github.com/TypeCellOS/BlockNote/blob/bea361e39846c26d9729a777a5cd3de1f48e8c3e/packages/core/src/editor/BlockNoteExtensions.ts#L78C5-L78C9), and add it manually with target: null as an option. Have you tried this?

It would probably require improving the API so TipTap extensions can be more easily customized. Would be happy to accept a PR for that!

EvanParden commented 1 month ago

I solved this problem by just adding a url pram ?id= and letting it open up a new note on a different page

DemienThor commented 2 weeks ago

Hi @YousefED ! Could you please share your thoughts of how can I remove Link and then add it manually? I've tried something like this:

import Link from '@tiptap/extension-link';

const editor = useCreateBlockNote();
editor._tiptapEditor.extensionManager.extensions = editor._tiptapEditor.extensionManager.extensions.filter(e => e.name !== 'link');

const linkPlugin = Link.configure({
    HTMLAttributes: {
      target: null,
    },
    openOnClick: 'whenNotEditable',
  });

editor._tiptapEditor.extensionManager.extensions.push(linkPlugin);

But it seems it doesn't work. If I'm not adding Link plugin - it seems to be removed correctly. But when I add it with target: null the Link plugin continues creating links with target: '_blank'.

matthewlipski commented 1 week ago

858 seems to be what you're looking for and should be merged soon! Since then you'll be able to disable the default Link extension with the disableExtensions editor option and add your own with the _tiptapOptions.extensions editor option.