diff --git a/src/sidepanel/details/linkify-new-tab.tsx b/src/sidepanel/details/linkify-new-tab.tsx
new file mode 100644
index 0000000..eefc27d
--- /dev/null
+++ b/src/sidepanel/details/linkify-new-tab.tsx
@@ -0,0 +1,23 @@
+import Linkify from 'react-linkify';
+
+interface Props {
+ children: React.ReactNode;
+}
+
+/**
+ * A wrapper component that uses react-linkify to convert any plain text URLs
+ * within its children into clickable links that open in a new tab.
+ */
+export function LinkifyNewTab({children}: Props) {
+ return (
+ (
+
+ {decoratedText}
+
+ )}
+ >
+ {children}
+
+ );
+}
diff --git a/src/sidepanel/details/multiline-text.tsx b/src/sidepanel/details/multiline-text.tsx
index 8eb66a9..45eaf13 100644
--- a/src/sidepanel/details/multiline-text.tsx
+++ b/src/sidepanel/details/multiline-text.tsx
@@ -1,4 +1,4 @@
-import Linkify from 'react-linkify';
+import {LinkifyNewTab} from './linkify-new-tab';
interface Props {
lines: (React.ReactNode | string)[];
@@ -9,7 +9,7 @@ export function MultilineText(props: Props) {
<>
{props.lines.map((line, index) => (
- {line}
+ {line}
))}
diff --git a/src/sidepanel/details/sources.tsx b/src/sidepanel/details/sources.tsx
index c563d3b..4e5cbdb 100644
--- a/src/sidepanel/details/sources.tsx
+++ b/src/sidepanel/details/sources.tsx
@@ -1,8 +1,8 @@
import {useIntl} from 'react-intl';
-import Linkify from 'react-linkify';
import {List} from 'semantic-ui-react';
import {formatDateOrRange} from '../../util/date_util';
import {Source} from '../../util/gedcom_util';
+import {LinkifyNewTab} from './linkify-new-tab';
interface Props {
sources?: Source[];
@@ -20,14 +20,14 @@ export function Sources({sources}: Props) {
-
+
{[source.author, source.title, source.publicationInfo]
.filter((sourceElement) => !!sourceElement)
.join(', ')}
-
+
- {source.page}
+ {source.page}
{source.date && ` [${formatDateOrRange(source.date, intl)}]`}