diff --git a/frontend/src/pages/xray/BalancersTab.vue b/frontend/src/pages/xray/BalancersTab.vue
index dc0145fa..94370886 100644
--- a/frontend/src/pages/xray/BalancersTab.vue
+++ b/frontend/src/pages/xray/BalancersTab.vue
@@ -20,6 +20,7 @@ const { t } = useI18n();
const props = defineProps({
templateSettings: { type: Object, default: null },
+ clientReverseTags: { type: Array, default: () => [] },
});
const STRATEGY_LABELS = {
@@ -40,11 +41,16 @@ const rows = computed(() => {
}));
});
-const outboundTags = computed(
- () => (props.templateSettings?.outbounds || [])
- .filter((o) => o.tag)
- .map((o) => o.tag),
-);
+const outboundTags = computed(() => {
+ const tags = new Set();
+ for (const o of props.templateSettings?.outbounds || []) {
+ if (o.tag) tags.add(o.tag);
+ }
+ for (const t of props.clientReverseTags || []) {
+ if (t) tags.add(t);
+ }
+ return [...tags];
+});
// === Modal state ====================================================
const modalOpen = ref(false);
diff --git a/frontend/src/pages/xray/RoutingTab.vue b/frontend/src/pages/xray/RoutingTab.vue
index beb28ca9..902d342d 100644
--- a/frontend/src/pages/xray/RoutingTab.vue
+++ b/frontend/src/pages/xray/RoutingTab.vue
@@ -70,6 +70,10 @@ const inboundTagOptions = computed(() => {
if (ib.tag) out.add(ib.tag);
}
for (const t of props.inboundTags || []) out.add(t);
+ for (const ob of props.templateSettings?.outbounds || []) {
+ const rt = ob?.reverse?.tag || ob?.settings?.reverse?.tag;
+ if (rt) out.add(rt);
+ }
// dnsTag if DNS is configured.
const dt = props.templateSettings?.dns?.tag;
if (dt) out.add(dt);
diff --git a/frontend/src/pages/xray/XrayPage.vue b/frontend/src/pages/xray/XrayPage.vue
index 42723616..bf5ed8b9 100644
--- a/frontend/src/pages/xray/XrayPage.vue
+++ b/frontend/src/pages/xray/XrayPage.vue
@@ -306,7 +306,10 @@ function confirmRestart() {
{{ t('pages.xray.Balancers') }}
-
+