diff --git a/ext/reverse_search_links/icons/ascii2d.ico b/ext/reverse_search_links/icons/ascii2d.ico
new file mode 100644
index 00000000..29e6fd12
Binary files /dev/null and b/ext/reverse_search_links/icons/ascii2d.ico differ
diff --git a/ext/reverse_search_links/icons/saucenao.ico b/ext/reverse_search_links/icons/saucenao.ico
new file mode 100644
index 00000000..128dde64
Binary files /dev/null and b/ext/reverse_search_links/icons/saucenao.ico differ
diff --git a/ext/reverse_search_links/icons/tineye.ico b/ext/reverse_search_links/icons/tineye.ico
new file mode 100644
index 00000000..184b8793
Binary files /dev/null and b/ext/reverse_search_links/icons/tineye.ico differ
diff --git a/ext/reverse_search_links/icons/trace.moe.ico b/ext/reverse_search_links/icons/trace.moe.ico
new file mode 100644
index 00000000..ff23d4f1
Binary files /dev/null and b/ext/reverse_search_links/icons/trace.moe.ico differ
diff --git a/ext/reverse_search_links/icons/yandex.ico b/ext/reverse_search_links/icons/yandex.ico
new file mode 100644
index 00000000..984e71c0
Binary files /dev/null and b/ext/reverse_search_links/icons/yandex.ico differ
diff --git a/ext/reverse_search_links/info.php b/ext/reverse_search_links/info.php
new file mode 100644
index 00000000..15f6164b
--- /dev/null
+++ b/ext/reverse_search_links/info.php
@@ -0,0 +1,18 @@
+ 'joe@thisisjoes.site'];
+ public string $license = self::LICENSE_GPLV2;
+ public string $description = "Provides reverse search links for images.";
+ public ?string $documentation = "Click on an icon in the 'Reverse Image Search' block to search for the image using the corresponding service. This may be useful to find the original source or author of an image.
+ Options for which services to show and the position and priority of the block are available for admins on the config page.";
+}
diff --git a/ext/reverse_search_links/main.php b/ext/reverse_search_links/main.php
new file mode 100644
index 00000000..9c68bb64
--- /dev/null
+++ b/ext/reverse_search_links/main.php
@@ -0,0 +1,85 @@
+image->get_mime(), $supported_types)) {
+ $this->theme->reverse_search_block($page, $event->image);
+ }
+ }
+
+
+ /**
+ * Supported reverse search services
+ */
+ protected array $SERVICES = [
+ 'SauceNAO',
+ 'IQDB',
+ 'TinEye',
+ 'trace.moe',
+ 'ascii2d',
+ 'Yandex'
+ ];
+
+ private function get_options(): array
+ {
+ global $config;
+
+ $output = [];
+ $services = $this->SERVICES;
+ foreach ($services as $service) {
+ $output[$service] = $service;
+ }
+
+ return $output;
+ }
+
+ /**
+ * Generate the settings block
+ */
+ public function onSetupBuilding(SetupBuildingEvent $event)
+ {
+ $sb = $event->panel->create_new_block("Reverse Search Links");
+ $sb->start_table();
+ $sb->add_int_option("ext_reverse_search_links_priority", "Priority:");
+ $sb->add_choice_option("ext_reverse_search_links_position", ["Main page" => "main", "In navigation bar" => "left"], "
Position: ");
+ $sb->add_multichoice_option("ext_reverse_search_links_enabled_services", $this->get_options(), "Enabled Services", true);
+ $sb->end_table();
+ }
+
+ /**
+ * Set default config values
+ */
+ public function onInitExt(InitExtEvent $event)
+ {
+ global $config;
+ $config->set_default_int(ReverseSearchLinksConfig::PRIORITY, 20);
+ $config->set_default_string(ReverseSearchLinksConfig::POSITION, "main");
+ $config->set_default_array(
+ ReverseSearchLinksConfig::ENABLED_SERVICES,
+ ['SauceNAO', 'IQDB', 'TinEye', 'trace.moe', 'ascii2d', 'Yandex']
+ );
+ }
+}
diff --git a/ext/reverse_search_links/style.css b/ext/reverse_search_links/style.css
new file mode 100644
index 00000000..5ad622c0
--- /dev/null
+++ b/ext/reverse_search_links/style.css
@@ -0,0 +1,4 @@
+#Reverse_Image_Searchmain a,
+#Reverse_Image_Searchleft a {
+ padding: 0 5px;
+}
diff --git a/ext/reverse_search_links/theme.php b/ext/reverse_search_links/theme.php
new file mode 100644
index 00000000..592d07cf
--- /dev/null
+++ b/ext/reverse_search_links/theme.php
@@ -0,0 +1,37 @@
+ 'https://saucenao.com/search.php?url=' . url_escape(make_http($image->get_thumb_link())),
+ 'TinEye' => 'https://www.tineye.com/search/?url=' . url_escape(make_http($image->get_thumb_link())),
+ 'trace.moe' => 'https://trace.moe/?auto&url=' . url_escape(make_http($image->get_thumb_link())),
+ 'ascii2d' => 'https://ascii2d.net/search/url/' . url_escape(make_http($image->get_thumb_link())),
+ 'Yandex' => 'https://yandex.com/images/search?rpt=imageview&url=' . url_escape(make_http($image->get_thumb_link()))
+ ];
+
+ // only generate links for enabled reverse search services
+ $enabled_services = $config->get_array(ReverseSearchLinksConfig::ENABLED_SERVICES);
+
+ $html = "";
+ foreach($links as $name => $link) {
+ if (in_array($name, $enabled_services)) {
+ $icon_link = make_link("/ext/reverse_search_links/icons/" . strtolower($name) . ".ico");
+ $html .= "";
+ }
+ }
+
+ $position = $config->get_string(ReverseSearchLinksConfig::POSITION) ?? "main";
+ $priority = $config->get_int(ReverseSearchLinksConfig::PRIORITY) ?? 20;
+
+ $page->add_block(new Block("Reverse Image Search", $html, $position, $priority));
+ }
+}