131

I have an onClick (React) handler on a table cell that fires properly, however I want to maintain the "Open in a new Tab" feature that having an href on a tag gives you.

Trying to combine both on a single element doesn't work as expected, of course:

<td onClick={this.someFunction} href="someLink">
  ...some content
<td>

Previously I looked into having an anchor tag nested inside the table cell span the full height, so whenever the contents of the cell were right-clicked, I could "Open in a New Tab" and still keep an onClick handler on the table cell element. However there's various problems with that approach, outlined here.

TLDR: Overriding causes other problems. Solutions have various compatibility issues.

So I ditched that approach for the one explained above. Ideas/suggestions? Is there a way to have the option "Open in a New Tab" without having to use an anchor/href?

Jose
  • 4,880
  • 8
  • 27
  • 49
  • Possibly a duplicate of this: https://stackoverflow.com/questions/4907843/open-a-url-in-a-new-tab-and-not-a-new-window-using-javascript – maxhallinan Jul 11 '17 at 23:39
  • href on a table cell element? – Roko C. Buljan Jul 12 '17 at 00:28
  • @RokoC.Buljan Yeah I know how strange that sounds. I was just showing that as an example. Originally it was just an anchor tag with an `href` inside of the table cell, but getting that anchor tag to span the full height does not appear to be a viable option without messing with the positioning. – Jose Jul 12 '17 at 02:53

5 Answers5

204

You have two options here, you can make it open in a new window/tab with JS:

<td onClick={()=> window.open("someLink", "_blank")}>text</td>

But a better option is to use a regular link but style it as a table cell:

<a style={{display: "table-cell"}} href="someLink" target="_blank">text</a>
gunn
  • 8,999
  • 2
  • 24
  • 24
107

Most Secure Solution, JS only

As mentioned by alko989, there is a major security flaw with _blank (details here).

To avoid it from pure JS code:

const openInNewTab = (url) => {
  const newWindow = window.open(url, '_blank', 'noopener,noreferrer')
  if (newWindow) newWindow.opener = null
}

Then add to your onClick

onClick={() => openInNewTab('https://stackoverflow.com')}

To be even terser in react, you can directly return a function

const onClickUrl = (url) => {
  return () => openInNewTab(url)
}

onClick={onClickUrl('https://stackoverflow.com')}

For Typescript + React, here is what these would look like:

export const openInNewTab = (url: string): void => {
  const newWindow = window.open(url, '_blank', 'noopener,noreferrer')
  if (newWindow) newWindow.opener = null
}

export const onClickUrl = (url: string): (() => void) => () => openInNewTab(url)

The third window.open param can also take these optional values, based on your needs.

Gibolt
  • 42,564
  • 15
  • 187
  • 127
  • What does it do exactly? `if (newWindow) newWindow.opener = null` I tried to console.log newWindow but it returns null always. – cyonder Sep 18 '20 at 23:23
  • 1
    I'm not sure which contexts return non-null values, but the spec is to return a window reference https://developer.mozilla.org/en-US/docs/Web/API/Window/open – Gibolt Sep 18 '20 at 23:50
  • 1
    This is the best response – BoyePanthera Nov 07 '20 at 23:30
28

The answer from @gunn is correct, target="_blank makes the link open in a new tab.

But this can be a security risk for you page; you can read about it here. There is a simple solution for that: adding rel="noopener noreferrer".

<a style={{display: "table-cell"}} href = "someLink" target = "_blank" 
rel = "noopener noreferrer">text</a>
alko989
  • 7,688
  • 5
  • 39
  • 62
8

React + TypeScript inline util method:

const navigateToExternalUrl = (url: string, shouldOpenNewTab: boolean = true) =>
shouldOpenNewTab ? window.open(url, "_blank") : window.location.href = url;
Luca Davanzo
  • 21,000
  • 15
  • 120
  • 146
5

Above answers are correct. But simply this worked for me

target={"_blank"}
FF new
  • 113
  • 1
  • 2
  • 11