diff --git a/src/App/Controller/SwitchyController.php b/src/App/Controller/SwitchyController.php
new file mode 100644
index 0000000..bcba245
--- /dev/null
+++ b/src/App/Controller/SwitchyController.php
@@ -0,0 +1,62 @@
+setHeaders(['content-type' => 'text/plain']);
+
+ $sites = SiteFactory::normalizeArray($this->request->getQueryParameters()['site'] ?? []);
+ $data = $this->request->getQueryParameter('data') ?? '';
+ if ($data != 'domains') {
+ return "# Error: The 'data' GET parameter is must be 'domains'";
+ }
+
+ $response = [
+ '; Switchy - RuleList',
+ '; Date: ' . date('Y-m-d'),
+ '; URL: ' .
+ $this->getBaseURL() .
+ '/?format=switchy&data=domains' .
+ (count($sites)
+ ? '&' . implode('&', array_map(fn(string $site) => 'site=' . urlencode($site), $sites))
+ : ''),
+ '',
+ '#BEGIN',
+ '',
+ '[Wildcard]',
+ ];
+
+ $domains = [];
+ if (count($sites)) {
+ foreach ($sites as $site) {
+ $domains = array_merge(
+ $domains,
+ array_map($this->wildcardFormat(...), $this->service->sites[$site]->$data)
+ );
+ }
+ } else {
+ foreach ($this->service->sites as $siteEntity) {
+ $domains = array_merge($domains, array_map($this->wildcardFormat(...), $siteEntity->$data));
+ }
+ }
+
+ $response = array_merge($response, SiteFactory::normalizeArray($domains));
+ $response = array_merge($response, ['', '#END']);
+
+ return implode("\n", $response);
+ }
+
+ /**
+ * @param string $domain
+ * @return string
+ */
+ private function wildcardFormat(string $domain): string {
+ return '*' . $domain . '/*';
+ }
+}
diff --git a/src/App/Template/IndexTemplate.php b/src/App/Template/IndexTemplate.php
index e32c5e4..0b6cbb8 100644
--- a/src/App/Template/IndexTemplate.php
+++ b/src/App/Template/IndexTemplate.php
@@ -614,6 +614,7 @@ use OpenCCK\App\Controller\TextController;
+