diff --git a/data/gresource.xml b/data/gresource.xml
index a4d2e5a0c..d3b6ef86d 100644
--- a/data/gresource.xml
+++ b/data/gresource.xml
@@ -93,6 +93,8 @@
         <file>ui/widgets/status.ui</file>
         <file>ui/widgets/votebox.ui</file>
         <file>ui/widgets/preview_card.ui</file>
+        <file>ui/widgets/preview_card_internal.ui</file>
+        <file>ui/widgets/preview_card_explore.ui</file>
         <file>ui/widgets/profile.ui</file>
         <file>ui/dialogs/admin_dashboard.ui</file>
         <file>ui/dialogs/list_edit.ui</file>
diff --git a/data/ui/widgets/preview_card.ui b/data/ui/widgets/preview_card.ui
index 901649fbd..43036eabd 100644
--- a/data/ui/widgets/preview_card.ui
+++ b/data/ui/widgets/preview_card.ui
@@ -12,74 +12,7 @@
 					<class name="flat" />
 				</style>
 				<child>
-					<object class="GtkBox" id="box">
-						<property name="orientation">vertical</property>
-						<child>
-							<object class="GtkBox">
-								<property name="orientation">vertical</property>
-								<property name="spacing">3</property>
-								<property name="valign">center</property>
-								<property name="hexpand">1</property>
-								<property name="margin-top">12</property>
-								<property name="margin-start">12</property>
-								<property name="margin-end">12</property>
-								<property name="margin-bottom">12</property>
-								<child>
-									<object class="GtkLabel" id="author_label">
-										<property name="ellipsize">end</property>
-										<property name="halign">start</property>
-										<property name="single-line-mode">1</property>
-										<style>
-											<class name="dim-label" />
-											<class name="caption" />
-										</style>
-									</object>
-								</child>
-								<child>
-									<object class="GtkLabel" id="title_label">
-										<property name="visible">0</property>
-										<property name="ellipsize">end</property>
-										<property name="halign">fill</property>
-										<property name="xalign">0</property>
-										<property name="lines">2</property>
-										<property name="wrap">1</property>
-										<property name="wrap-mode">word-char</property>
-										<style>
-											<class name="font-bold" />
-										</style>
-									</object>
-								</child>
-								<child>
-									<object class="GtkLabel" id="description_label">
-										<property name="visible">0</property>
-										<property name="ellipsize">end</property>
-										<property name="halign">fill</property>
-										<property name="xalign">0</property>
-										<property name="lines">3</property>
-										<property name="wrap">1</property>
-										<property name="wrap-mode">word-char</property>
-										<property name="single-line-mode">1</property>
-										<style>
-											<class name="caption" />
-										</style>
-									</object>
-								</child>
-								<child>
-									<object class="GtkLabel" id="used_times_label">
-										<property name="visible">0</property>
-										<property name="halign">fill</property>
-										<property name="xalign">0</property>
-										<property name="wrap">1</property>
-										<property name="wrap-mode">word-char</property>
-										<style>
-											<class name="dim-label" />
-											<class name="caption" />
-										</style>
-									</object>
-								</child>
-							</object>
-						</child>
-					</object>
+					<object class="TubaWidgetsPreviewCardInternal" id="box" />
 				</child>
 			</object>
 		</child>
diff --git a/data/ui/widgets/preview_card_explore.ui b/data/ui/widgets/preview_card_explore.ui
new file mode 100644
index 000000000..74d90fa28
--- /dev/null
+++ b/data/ui/widgets/preview_card_explore.ui
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+	<requires lib="gtk" version="4.0" />
+	<template class="TubaWidgetsPreviewCardExplore" parent="GtkListBoxRow">
+		<style>
+			<class name="preview_card" />
+			<class name="explore" />
+		</style>
+		<child>
+			<object class="TubaWidgetsPreviewCardInternal" id="box">
+				<property name="orientation">horizontal</property>
+				<property name="homogeneous">1</property>
+			</object>
+		</child>
+	</template>
+</interface>
diff --git a/data/ui/widgets/preview_card_internal.ui b/data/ui/widgets/preview_card_internal.ui
new file mode 100644
index 000000000..37d0607cc
--- /dev/null
+++ b/data/ui/widgets/preview_card_internal.ui
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+	<requires lib="gtk" version="4.0" />
+	<template class="TubaWidgetsPreviewCardInternal" parent="GtkBox">
+		<property name="orientation">vertical</property>
+		<child>
+			<object class="GtkBox" id="internal_box">
+				<property name="orientation">vertical</property>
+				<property name="spacing">3</property>
+				<property name="valign">center</property>
+				<property name="hexpand">1</property>
+				<property name="margin-top">12</property>
+				<property name="margin-start">12</property>
+				<property name="margin-end">12</property>
+				<property name="margin-bottom">12</property>
+				<child>
+					<object class="GtkLabel" id="author_label">
+						<property name="ellipsize">end</property>
+						<property name="halign">start</property>
+						<property name="single-line-mode">1</property>
+						<style>
+							<class name="dim-label" />
+							<class name="caption" />
+						</style>
+					</object>
+				</child>
+				<child>
+					<object class="GtkLabel" id="title_label">
+						<property name="visible">0</property>
+						<property name="ellipsize">end</property>
+						<property name="halign">fill</property>
+						<property name="xalign">0</property>
+						<property name="lines">2</property>
+						<property name="wrap">1</property>
+						<property name="wrap-mode">word-char</property>
+						<style>
+							<class name="font-bold" />
+						</style>
+					</object>
+				</child>
+				<child>
+					<object class="GtkLabel" id="description_label">
+						<property name="visible">0</property>
+						<property name="ellipsize">end</property>
+						<property name="halign">fill</property>
+						<property name="xalign">0</property>
+						<property name="lines">3</property>
+						<property name="wrap">1</property>
+						<property name="wrap-mode">word-char</property>
+						<property name="single-line-mode">1</property>
+						<style>
+							<class name="caption" />
+						</style>
+					</object>
+				</child>
+			</object>
+		</child>
+	</template>
+</interface>
diff --git a/src/API/Instance.vala b/src/API/Instance.vala
index 9950393f6..e1462fd16 100644
--- a/src/API/Instance.vala
+++ b/src/API/Instance.vala
@@ -17,6 +17,7 @@ public class Tuba.API.Instance : Entity {
 	public Gee.ArrayList<Rule>? rules { get; set; }
 
 	public bool tuba_can_translate { get; set; default=false; }
+	public int8 tuba_mastodon_version { get; set; default=0; }
 
 	public override Type deserialize_array_type (string prop) {
 		switch (prop) {
diff --git a/src/API/InstanceV2.vala b/src/API/InstanceV2.vala
index ccdc2d718..104602f9f 100644
--- a/src/API/InstanceV2.vala
+++ b/src/API/InstanceV2.vala
@@ -6,7 +6,12 @@ public class Tuba.API.InstanceV2 : Entity {
 		public Translation translation { get; set; default = null; }
 	}
 
+	public class APIVersions : Entity {
+		public int8 mastodon { get; set; default = 0; }
+	}
+
 	public Configuration configuration { get; set; default = null; }
+	public APIVersions? api_versions { get; set; default = null; }
 
 	public static InstanceV2 from (Json.Node node) throws Error {
 		return Entity.from_json (typeof (API.InstanceV2), node) as API.InstanceV2;
diff --git a/src/API/Status/PreviewCard.vala b/src/API/Status/PreviewCard.vala
index f1ecabba9..6013d2e9f 100644
--- a/src/API/Status/PreviewCard.vala
+++ b/src/API/Status/PreviewCard.vala
@@ -168,6 +168,8 @@ public class Tuba.API.PreviewCard : Entity, Widgetizable {
 	}
 
 	public override Gtk.Widget to_widget () {
+		if (this.kind == "link" && this.history != null) return new Widgets.PreviewCardExplore (this);
+
 		return new Widgets.PreviewCard (this);
 	}
 
diff --git a/src/Services/Accounts/InstanceAccount.vala b/src/Services/Accounts/InstanceAccount.vala
index 194b7266a..3e414f8b9 100644
--- a/src/Services/Accounts/InstanceAccount.vala
+++ b/src/Services/Accounts/InstanceAccount.vala
@@ -466,8 +466,12 @@ public class Tuba.InstanceAccount : API.Account, Streamable {
 				this.probably_has_notification_filters = true;
 				var instance_v2 = API.InstanceV2.from (node);
 
-				if (instance_v2 != null && instance_v2.configuration != null && instance_v2.configuration.translation != null) {
-					this.instance_info.tuba_can_translate = instance_v2.configuration.translation.enabled;
+				if (instance_v2 != null) {
+					if (instance_v2.configuration != null && instance_v2.configuration.translation != null)
+						this.instance_info.tuba_can_translate = instance_v2.configuration.translation.enabled;
+
+					if (instance_v2.api_versions != null && instance_v2.api_versions.mastodon > 0)
+						this.instance_info.tuba_mastodon_version = instance_v2.api_versions.mastodon;
 				}
 			})
 			.exec ();
diff --git a/src/Views/ContentBase.vala b/src/Views/ContentBase.vala
index 1506c08b1..5768d21d0 100644
--- a/src/Views/ContentBase.vala
+++ b/src/Views/ContentBase.vala
@@ -122,22 +122,13 @@ public class Tuba.Views.ContentBase : Views.Base {
 
 			#if !USE_LISTVIEW
 				Gtk.Widget widget = obj_widgetable.to_widget ();
-				if (widget as Widgets.PreviewCard == null) {
-					widget.add_css_class ("card");
-					widget.add_css_class ("card-spacing");
-					widget.focusable = true;
-
-					// Thread lines overflow slightly
-					widget.overflow = Gtk.Overflow.HIDDEN;
-					return widget;
-				}
-
-				return new Gtk.ListBoxRow () {
-					css_classes = { "card", "card-spacing" },
-					focusable = false,
-					overflow = Gtk.Overflow.HIDDEN,
-					child = widget
-				};
+				widget.add_css_class ("card");
+				widget.add_css_class ("card-spacing");
+				widget.focusable = true;
+
+				// Thread lines overflow slightly
+				widget.overflow = Gtk.Overflow.HIDDEN;
+				return widget;
 			#else
 				return obj_widgetable.to_widget ();
 			#endif
diff --git a/src/Views/Link.vala b/src/Views/Link.vala
new file mode 100644
index 000000000..215facba6
--- /dev/null
+++ b/src/Views/Link.vala
@@ -0,0 +1,9 @@
+public class Tuba.Views.Link : Views.Timeline {
+	public Link (string link) {
+		Object (
+			url: @"/api/v1/timelines/link?url=$(Uri.escape_string (link))",
+			label: link,
+			icon: "tuba-globe-symbolic"
+		);
+	}
+}
diff --git a/src/Views/meson.build b/src/Views/meson.build
index a1c235948..81d12a65c 100644
--- a/src/Views/meson.build
+++ b/src/Views/meson.build
@@ -13,6 +13,7 @@ sources += files(
     'Hashtag.vala',
     'Hashtags.vala',
     'Home.vala',
+    'Link.vala',
     'List.vala',
     'Lists.vala',
     'Local.vala',
diff --git a/src/Widgets/PreviewCard.vala b/src/Widgets/PreviewCard.vala
index 393e2384a..cddcb2d21 100644
--- a/src/Widgets/PreviewCard.vala
+++ b/src/Widgets/PreviewCard.vala
@@ -5,11 +5,7 @@ public class Tuba.Widgets.PreviewCard : Gtk.Box {
 	}
 
 	[GtkChild] public unowned Gtk.Button button;
-	[GtkChild] unowned Gtk.Box box;
-	[GtkChild] unowned Gtk.Label author_label;
-	[GtkChild] unowned Gtk.Label title_label;
-	[GtkChild] unowned Gtk.Label description_label;
-	[GtkChild] unowned Gtk.Label used_times_label;
+	[GtkChild] unowned Widgets.PreviewCardInternal box;
 
 	private Gee.ArrayList<API.PreviewCard.AuthorEntity>? verified_authors = null;
 	private string? author_url = null;
@@ -73,57 +69,19 @@ public class Tuba.Widgets.PreviewCard : Gtk.Box {
 				if (host != null) author = host;
 			} catch {}
 		}
-		author_label.label = author;
+		box.author_label.label = author;
 
 		if (card_obj.title != "") {
-			title_label.label = title_label.tooltip_text = card_obj.title.replace ("\n", " ").strip ();
-			title_label.visible = true;
+			box.title_label.label = box.title_label.tooltip_text = card_obj.title.replace ("\n", " ").strip ();
+			box.title_label.visible = true;
 		}
 
 		if (card_obj.description != "") {
-			description_label.label = description_label.tooltip_text = card_obj.description;
-			description_label.visible = true;
+			box.description_label.label = box.description_label.tooltip_text = card_obj.description;
+			box.description_label.visible = true;
 		}
 
-		if (card_obj.kind == "link" && card_obj.history != null && card_obj.history.size > 0) {
-				box.orientation = Gtk.Orientation.HORIZONTAL;
-				box.homogeneous = true;
-				image_widget.height_request = 70;
-				image_widget.add_css_class ("preview_card_h");
-				image_widget.remove_css_class ("preview_card_v");
-
-				button.add_css_class ("explore");
-				button.remove_css_class ("frame");
-				button.clicked.connect (() => Host.open_url (card_obj.url));
-
-				if (description_label.visible) {
-					if (description_label.label.length > 109)
-						description_label.label = description_label.label.replace ("\n", " ").substring (0, 109) + "…";
-					description_label.single_line_mode = false;
-					description_label.ellipsize = Pango.EllipsizeMode.NONE;
-					description_label.wrap = true;
-					description_label.wrap_mode = Pango.WrapMode.WORD_CHAR;
-				}
-
-				var last_history_entry = card_obj.history.get (0);
-				var total_uses = int.parse (last_history_entry.uses);
-				var total_accounts = int.parse (last_history_entry.accounts);
-				// translators: the variables are numbers
-				var subtitle = _("Discussed %d times by %d people yesterday").printf (total_uses, total_accounts);
-
-				if (card_obj.history.size > 1) {
-					last_history_entry = card_obj.history.get (1);
-					total_uses += int.parse (last_history_entry.uses);
-					total_accounts += int.parse (last_history_entry.accounts);
-
-					// translators: the variables are numbers
-					subtitle = _("Discussed %d times by %d people in the past 2 days")
-						.printf (total_uses, total_accounts);
-				}
-
-				used_times_label.label = subtitle;
-				used_times_label.visible = true;
-		} else if (card_obj.authors != null && card_obj.authors.size > 0) {
+		if (card_obj.authors != null && card_obj.authors.size > 0) {
 			bool should_add = true;
 
 			Gtk.Widget more_from_button = new Gtk.Button () {
diff --git a/src/Widgets/PreviewCardExplore.vala b/src/Widgets/PreviewCardExplore.vala
new file mode 100644
index 000000000..3a6bbc772
--- /dev/null
+++ b/src/Widgets/PreviewCardExplore.vala
@@ -0,0 +1,118 @@
+[GtkTemplate (ui = "/dev/geopjr/Tuba/ui/widgets/preview_card_explore.ui")]
+public class Tuba.Widgets.PreviewCardExplore : Gtk.ListBoxRow {
+	~PreviewCardExplore () {
+		debug ("Destroying PreviewCardExplore");
+	}
+
+	[GtkChild] unowned Widgets.PreviewCardInternal box;
+
+	private string url;
+	public signal void open ();
+
+	public PreviewCardExplore (API.PreviewCard card_obj) {
+		this.url = card_obj.url;
+		this.activate.connect (on_card_click);
+		this.open.connect (on_card_click);
+
+		Gtk.Widget image_widget;
+		if (card_obj.image != null) {
+			image_widget = new Gtk.Picture () {
+				width_request = 25,
+				content_fit = Gtk.ContentFit.COVER,
+				height_request = 250,
+				css_classes = {"preview_card_h"}
+			};
+
+			Tuba.Helper.Image.request_paintable (card_obj.image, card_obj.blurhash, false, (paintable) => {
+				((Gtk.Picture) image_widget).paintable = paintable;
+			});
+		} else {
+			image_widget = new Gtk.Image.from_icon_name ("tuba-earth-symbolic") {
+				css_classes = {"preview_card_h"},
+				icon_size = Gtk.IconSize.LARGE,
+				width_request = 70,
+			};
+		}
+		image_widget.height_request = 70;
+		box.prepend (image_widget);
+
+		var author = card_obj.provider_name;
+		if (author == "") {
+			try {
+				var uri = GLib.Uri.parse (card_obj.url, GLib.UriFlags.NONE);
+				var host = uri.get_host ();
+				if (host != null) author = host;
+			} catch {}
+		}
+		box.author_label.label = author;
+
+		if (card_obj.title != "") {
+			box.title_label.label = box.title_label.tooltip_text = card_obj.title.replace ("\n", " ").strip ();
+			box.title_label.visible = true;
+		}
+
+		if (card_obj.description != "") {
+			box.description_label.label = box.description_label.tooltip_text = card_obj.description;
+			box.description_label.visible = true;
+			box.description_label.single_line_mode = false;
+			box.description_label.ellipsize = Pango.EllipsizeMode.NONE;
+			box.description_label.wrap = true;
+			box.description_label.wrap_mode = Pango.WrapMode.WORD_CHAR;
+
+			if (box.description_label.label.length > 109)
+						box.description_label.label = box.description_label.label.replace ("\n", " ").substring (0, 109) + "…";
+		}
+
+
+		var last_history_entry = card_obj.history.get (0);
+		var total_uses = int.parse (last_history_entry.uses);
+		var total_accounts = int.parse (last_history_entry.accounts);
+		// translators: the variables are numbers
+		var subtitle = _("Discussed %d times by %d people yesterday").printf (total_uses, total_accounts);
+
+		if (card_obj.history.size > 1) {
+			last_history_entry = card_obj.history.get (1);
+			total_uses += int.parse (last_history_entry.uses);
+			total_accounts += int.parse (last_history_entry.accounts);
+
+			// translators: the variables are numbers
+			subtitle = _("Discussed %d times by %d people in the past 2 days")
+				.printf (total_uses, total_accounts);
+		}
+
+		var used_times_label = new Gtk.Label (subtitle) {
+			xalign = 0.0f,
+			wrap = true,
+			wrap_mode = Pango.WrapMode.WORD_CHAR,
+			css_classes = { "caption" }
+		};
+
+		if (accounts.active.instance_info.tuba_mastodon_version >= 1) {
+			Gtk.Button discussions_button = new Gtk.Button () {
+				child = used_times_label,
+				// translators: tooltip text on 'explore' tab button to
+				//				see posts where the selected article is
+				//				being discussed.
+				tooltip_text = _("See Discussions"),
+
+				// Looks weird flat, as it doesn't indicate
+				// that it's clickable, plus it's not dimmed and
+				// has padding. Looks out of place.
+				//  css_classes = { "flat" },
+			};
+			discussions_button.clicked.connect (on_link_timeline_open);
+			box.internal_box.append (discussions_button);
+		} else {
+			used_times_label.add_css_class ("dim-label");
+			box.internal_box.append (used_times_label);
+		}
+	}
+
+	private void on_link_timeline_open () {
+		app.main_window.open_view (new Views.Link (this.url));
+	}
+
+	private void on_card_click () {
+		Host.open_url (this.url);
+	}
+}
diff --git a/src/Widgets/PreviewCardInternal.vala b/src/Widgets/PreviewCardInternal.vala
new file mode 100644
index 000000000..9e51086b8
--- /dev/null
+++ b/src/Widgets/PreviewCardInternal.vala
@@ -0,0 +1,7 @@
+[GtkTemplate (ui = "/dev/geopjr/Tuba/ui/widgets/preview_card_internal.ui")]
+public class Tuba.Widgets.PreviewCardInternal : Gtk.Box {
+	[GtkChild] public unowned Gtk.Label author_label;
+	[GtkChild] public unowned Gtk.Label title_label;
+	[GtkChild] public unowned Gtk.Label description_label;
+	[GtkChild] public unowned Gtk.Box internal_box;
+}
diff --git a/src/Widgets/meson.build b/src/Widgets/meson.build
index b011216c0..3d8ad1bc7 100644
--- a/src/Widgets/meson.build
+++ b/src/Widgets/meson.build
@@ -15,6 +15,8 @@ sources += files(
     'Notification.vala',
     'NotificationRequest.vala',
     'PreviewCard.vala',
+    'PreviewCardInternal.vala',
+    'PreviewCardExplore.vala',
     'ProfileCover.vala',
     'RelationshipButton.vala',
     'RichLabel.vala',