diff --git a/sub/sub.go b/sub/sub.go
index 0605c8b9..1dcd9601 100644
--- a/sub/sub.go
+++ b/sub/sub.go
@@ -153,6 +153,31 @@ func (s *Server) initRouter() (*gin.Engine, error) {
SubTitle = ""
}
+ SubSupportUrl, err := s.settingService.GetSubSupportUrl()
+ if err != nil {
+ SubSupportUrl = ""
+ }
+
+ SubProfileUrl, err := s.settingService.GetSubProfileUrl()
+ if err != nil {
+ SubProfileUrl = ""
+ }
+
+ SubAnnounce, err := s.settingService.GetSubAnnounce()
+ if err != nil {
+ SubAnnounce = ""
+ }
+
+ SubEnableRouting, err := s.settingService.GetSubEnableRouting()
+ if err != nil {
+ return nil, err
+ }
+
+ SubRoutingRules, err := s.settingService.GetSubRoutingRules()
+ if err != nil {
+ SubRoutingRules = ""
+ }
+
// set per-request localizer from headers/cookies
engine.Use(locale.LocalizerMiddleware())
@@ -231,7 +256,8 @@ func (s *Server) initRouter() (*gin.Engine, error) {
s.sub = NewSUBController(
g, LinksPath, JsonPath, subJsonEnable, Encrypt, ShowInfo, RemarkModel, SubUpdates,
- SubJsonFragment, SubJsonNoises, SubJsonMux, SubJsonRules, SubTitle)
+ SubJsonFragment, SubJsonNoises, SubJsonMux, SubJsonRules, SubTitle, SubSupportUrl,
+ SubProfileUrl, SubAnnounce, SubEnableRouting, SubRoutingRules)
return engine, nil
}
diff --git a/sub/subController.go b/sub/subController.go
index ec574d6e..7653a4e1 100644
--- a/sub/subController.go
+++ b/sub/subController.go
@@ -4,6 +4,7 @@ import (
"encoding/base64"
"fmt"
"strings"
+ "strconv"
"github.com/mhsanaei/3x-ui/v2/config"
@@ -12,12 +13,17 @@ import (
// SUBController handles HTTP requests for subscription links and JSON configurations.
type SUBController struct {
- subTitle string
- subPath string
- subJsonPath string
- jsonEnabled bool
- subEncrypt bool
- updateInterval string
+ subTitle string
+ subSupportUrl string
+ subProfileUrl string
+ subAnnounce string
+ subEnableRouting bool
+ subRoutingRules string
+ subPath string
+ subJsonPath string
+ jsonEnabled bool
+ subEncrypt bool
+ updateInterval string
subService *SubService
subJsonService *SubJsonService
@@ -38,18 +44,28 @@ func NewSUBController(
jsonMux string,
jsonRules string,
subTitle string,
+ subSupportUrl string,
+ subProfileUrl string,
+ subAnnounce string,
+ subEnableRouting bool,
+ subRoutingRules string,
) *SUBController {
sub := NewSubService(showInfo, rModel)
a := &SUBController{
- subTitle: subTitle,
- subPath: subPath,
- subJsonPath: jsonPath,
- jsonEnabled: jsonEnabled,
- subEncrypt: encrypt,
- updateInterval: update,
+ subTitle: subTitle,
+ subSupportUrl: subSupportUrl,
+ subProfileUrl: subProfileUrl,
+ subAnnounce: subAnnounce,
+ subEnableRouting: subEnableRouting,
+ subRoutingRules: subRoutingRules,
+ subPath: subPath,
+ subJsonPath: jsonPath,
+ jsonEnabled: jsonEnabled,
+ subEncrypt: encrypt,
+ updateInterval: update,
- subService: sub,
- subJsonService: NewSubJsonService(jsonFragment, jsonNoise, jsonMux, jsonRules, sub),
+ subService: sub,
+ subJsonService: NewSubJsonService(jsonFragment, jsonNoise, jsonMux, jsonRules, sub),
}
a.initRouter(g)
return a
@@ -127,7 +143,7 @@ func (a *SUBController) subs(c *gin.Context) {
// Add headers
header := fmt.Sprintf("upload=%d; download=%d; total=%d; expire=%d", traffic.Up, traffic.Down, traffic.Total, traffic.ExpiryTime/1000)
- a.ApplyCommonHeaders(c, header, a.updateInterval, a.subTitle)
+ a.ApplyCommonHeaders(c, header, a.updateInterval, a.subTitle, a.subSupportUrl, a.subProfileUrl, a.subAnnounce, a.subEnableRouting, a.subRoutingRules)
if a.subEncrypt {
c.String(200, base64.StdEncoding.EncodeToString([]byte(result)))
@@ -145,17 +161,31 @@ func (a *SUBController) subJsons(c *gin.Context) {
if err != nil || len(jsonSub) == 0 {
c.String(400, "Error!")
} else {
-
// Add headers
- a.ApplyCommonHeaders(c, header, a.updateInterval, a.subTitle)
+ a.ApplyCommonHeaders(c, header, a.updateInterval, a.subTitle, a.subSupportUrl, a.subProfileUrl, a.subAnnounce, a.subEnableRouting, a.subRoutingRules)
c.String(200, jsonSub)
}
}
// ApplyCommonHeaders sets common HTTP headers for subscription responses including user info, update interval, and profile title.
-func (a *SUBController) ApplyCommonHeaders(c *gin.Context, header, updateInterval, profileTitle string) {
+func (a *SUBController) ApplyCommonHeaders(
+ c *gin.Context,
+ header,
+ updateInterval,
+ profileTitle string,
+ profileSupportUrl string,
+ profileUrl string,
+ profileAnnounce string,
+ profileEnableRouting bool,
+ profileRoutingRules string,
+) {
c.Writer.Header().Set("Subscription-Userinfo", header)
c.Writer.Header().Set("Profile-Update-Interval", updateInterval)
c.Writer.Header().Set("Profile-Title", "base64:"+base64.StdEncoding.EncodeToString([]byte(profileTitle)))
+ c.Writer.Header().Set("Support-Url", profileSupportUrl)
+ c.Writer.Header().Set("Profile-Web-Page-Url", profileUrl)
+ c.Writer.Header().Set("Announce", "base64:"+base64.StdEncoding.EncodeToString([]byte(profileAnnounce)))
+ c.Writer.Header().Set("Routing-Enable", strconv.FormatBool(profileEnableRouting))
+ c.Writer.Header().Set("Routing", profileRoutingRules)
}
diff --git a/web/assets/js/model/setting.js b/web/assets/js/model/setting.js
index 53ffae1a..af80a63e 100644
--- a/web/assets/js/model/setting.js
+++ b/web/assets/js/model/setting.js
@@ -29,6 +29,11 @@ class AllSetting {
this.subEnable = true;
this.subJsonEnable = false;
this.subTitle = "";
+ this.subSupportUrl = "";
+ this.subProfileUrl = "";
+ this.subAnnounce = "";
+ this.subEnableRouting = true;
+ this.subRoutingRules = "";
this.subListen = "";
this.subPort = 2096;
this.subPath = "/sub/";
diff --git a/web/entity/entity.go b/web/entity/entity.go
index 42e2df85..40294925 100644
--- a/web/entity/entity.go
+++ b/web/entity/entity.go
@@ -57,6 +57,11 @@ type AllSetting struct {
SubEnable bool `json:"subEnable" form:"subEnable"` // Enable subscription server
SubJsonEnable bool `json:"subJsonEnable" form:"subJsonEnable"` // Enable JSON subscription endpoint
SubTitle string `json:"subTitle" form:"subTitle"` // Subscription title
+ SubSupportUrl string `json:"subSupportUrl" form:"subSupportUrl"` // Subscription support URL
+ SubProfileUrl string `json:"subProfileUrl" form:"subProfileUrl"` // Subscription profile URL
+ SubAnnounce string `json:"subAnnounce" form:"subAnnounce"` // Subscription announce
+ SubEnableRouting bool `json:"subEnableRouting" form:"subEnableRouting"` // Enable routing for subscription
+ SubRoutingRules string `json:"subRoutingRules" form:"subRoutingRules"` // Subscription global routing rules (Only for Happ)
SubListen string `json:"subListen" form:"subListen"` // Subscription server listen IP
SubPort int `json:"subPort" form:"subPort"` // Subscription server port
SubPath string `json:"subPath" form:"subPath"` // Base path for subscription URLs
diff --git a/web/html/settings/panel/subscription/general.html b/web/html/settings/panel/subscription/general.html
index e65b2738..5d83aa37 100644
--- a/web/html/settings/panel/subscription/general.html
+++ b/web/html/settings/panel/subscription/general.html
@@ -15,13 +15,6 @@
-
- {{ i18n "pages.settings.subTitle"}}
- {{ i18n "pages.settings.subTitleDesc"}}
-
-
-
-
{{ i18n "pages.settings.subListen"}}
{{ i18n "pages.settings.subListenDesc"}}
@@ -78,6 +71,50 @@
+ {{ i18n "pages.xray.basicTemplate"}}
+
+ {{ i18n "pages.settings.subTitle"}}
+ {{ i18n "pages.settings.subTitleDesc"}}
+
+
+
+
+
+ {{ i18n "pages.settings.subSupportUrl"}}
+ {{ i18n "pages.settings.subSupportUrlDesc"}}
+
+
+
+
+
+ {{ i18n "pages.settings.subProfileUrl"}}
+ {{ i18n "pages.settings.subProfileUrlDesc"}}
+
+
+
+
+
+ {{ i18n "pages.settings.subAnnounce"}}
+ {{ i18n "pages.settings.subAnnounceDesc"}}
+
+
+
+
+ {{ i18n "pages.xray.advancedTemplate"}} (Happ)
+
+ {{ i18n "pages.settings.subEnableRouting"}}
+ {{ i18n "pages.settings.subEnableRoutingDesc"}}
+
+
+
+
+
+ {{ i18n "pages.settings.subRoutingRules"}}
+ {{ i18n "pages.settings.subRoutingRulesDesc"}}
+
+
+
+
diff --git a/web/service/setting.go b/web/service/setting.go
index 56db346d..3fa37f44 100644
--- a/web/service/setting.go
+++ b/web/service/setting.go
@@ -53,6 +53,11 @@ var defaultValueMap = map[string]string{
"subEnable": "true",
"subJsonEnable": "false",
"subTitle": "",
+ "subSupportUrl": "",
+ "subProfileUrl": "",
+ "subAnnounce": "",
+ "subEnableRouting": "true",
+ "subRoutingRules": "",
"subListen": "",
"subPort": "2096",
"subPath": "/sub/",
@@ -459,6 +464,26 @@ func (s *SettingService) GetSubTitle() (string, error) {
return s.getString("subTitle")
}
+func (s *SettingService) GetSubSupportUrl() (string, error) {
+ return s.getString("subSupportUrl")
+}
+
+func (s *SettingService) GetSubProfileUrl() (string, error) {
+ return s.getString("subProfileUrl")
+}
+
+func (s *SettingService) GetSubAnnounce() (string, error) {
+ return s.getString("subAnnounce")
+}
+
+func (s *SettingService) GetSubEnableRouting() (bool, error) {
+ return s.getBool("subEnableRouting")
+}
+
+func (s *SettingService) GetSubRoutingRules() (string, error) {
+ return s.getString("subRoutingRules")
+}
+
func (s *SettingService) GetSubListen() (string, error) {
return s.getString("subListen")
}
diff --git a/web/translation/translate.ar_EG.toml b/web/translation/translate.ar_EG.toml
index 06a3e937..6d75d196 100644
--- a/web/translation/translate.ar_EG.toml
+++ b/web/translation/translate.ar_EG.toml
@@ -374,6 +374,16 @@
"subJsonEnable" = "تمكين/تعطيل نقطة نهاية اشتراك JSON بشكل مستقل."
"subTitle" = "عنوان الاشتراك"
"subTitleDesc" = "العنوان اللي هيظهر في عميل VPN"
+"subSupportUrl" = "رابط الدعم"
+"subSupportUrlDesc" = "رابط الدعم الفني المعروض في عميل VPN"
+"subProfileUrl" = "رابط الملف الشخصي"
+"subProfileUrlDesc" = "رابط لموقعك الإلكتروني يظهر في عميل VPN"
+"subAnnounce" = "إعلان"
+"subAnnounceDesc" = "نص الإعلان المعروض في عميل VPN"
+"subEnableRouting" = "تفعيل التوجيه"
+"subEnableRoutingDesc" = "إعداد عام لتمكين التوجيه (Routing) في عميل VPN. (فقط لـ Happ)"
+"subRoutingRules" = "قواعد التوجيه"
+"subRoutingRulesDesc" = "قواعد التوجيه العامة لعميل VPN. (فقط لـ Happ)"
"subListen" = "IP الاستماع"
"subListenDesc" = "عنوان IP لخدمة الاشتراك. (سيبه فاضي عشان يستمع على كل الـ IPs)"
"subPort" = "بورت الاستماع"
diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml
index 6da9185b..244e6f2c 100644
--- a/web/translation/translate.en_US.toml
+++ b/web/translation/translate.en_US.toml
@@ -374,6 +374,16 @@
"subJsonEnable" = "Enable/Disable the JSON subscription endpoint independently."
"subTitle" = "Subscription Title"
"subTitleDesc" = "Title shown in VPN client"
+"subSupportUrl" = "Support URL"
+"subSupportUrlDesc" = "Technical support link shown in the VPN client"
+"subProfileUrl" = "Profile URL"
+"subProfileUrlDesc" = "A link to your website displayed in the VPN client"
+"subAnnounce" = "Announce"
+"subAnnounceDesc" = "The text of the announce displayed in the VPN client"
+"subEnableRouting" = "Enable routing"
+"subEnableRoutingDesc" = "Global setting to enable routing in the VPN client. (Only for Happ)"
+"subRoutingRules" = "Routing rules"
+"subRoutingRulesDesc" = "Global routing rules for the VPN client. (Only for Happ)"
"subListen" = "Listen IP"
"subListenDesc" = "The IP address for the subscription service. (leave blank to listen on all IPs)"
"subPort" = "Listen Port"
diff --git a/web/translation/translate.es_ES.toml b/web/translation/translate.es_ES.toml
index ccd5beff..b0dde898 100644
--- a/web/translation/translate.es_ES.toml
+++ b/web/translation/translate.es_ES.toml
@@ -374,6 +374,16 @@
"subJsonEnable" = "Habilitar/Deshabilitar el endpoint de suscripción JSON de forma independiente."
"subTitle" = "Título de la Suscripción"
"subTitleDesc" = "Título mostrado en el cliente de VPN"
+"subSupportUrl" = "URL de soporte"
+"subSupportUrlDesc" = "Enlace de soporte técnico mostrado en el cliente VPN"
+"subProfileUrl" = "URL del perfil"
+"subProfileUrlDesc" = "Un enlace a tu sitio web mostrado en el cliente VPN"
+"subAnnounce" = "Anuncio"
+"subAnnounceDesc" = "El texto del anuncio mostrado en el cliente VPN"
+"subEnableRouting" = "Habilitar enrutamiento"
+"subEnableRoutingDesc" = "Configuración global para habilitar el enrutamiento en el cliente VPN. (Solo para Happ)"
+"subRoutingRules" = "Reglas de enrutamiento"
+"subRoutingRulesDesc" = "Reglas de enrutamiento globales para el cliente VPN. (Solo para Happ)"
"subListen" = "Listening IP"
"subListenDesc" = "Dejar en blanco por defecto para monitorear todas las IPs."
"subPort" = "Puerto de Suscripción"
diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml
index a25484d1..1eda5fb5 100644
--- a/web/translation/translate.fa_IR.toml
+++ b/web/translation/translate.fa_IR.toml
@@ -374,6 +374,16 @@
"subJsonEnable" = "فعال/غیرفعالسازی مستقل نقطه دسترسی سابسکریپشن JSON."
"subTitle" = "عنوان اشتراک"
"subTitleDesc" = "عنوان نمایش داده شده در کلاینت VPN"
+"subSupportUrl" = "آدرس پشتیبانی"
+"subSupportUrlDesc" = "لینک پشتیبانی فنی که در کلاینت VPN نمایش داده میشود"
+"subProfileUrl" = "آدرس پروفایل"
+"subProfileUrlDesc" = "لینک وبسایت شما که در کلاینت VPN نمایش داده میشود"
+"subAnnounce" = "اعلان"
+"subAnnounceDesc" = "متن اعلانی که در کلاینت VPN نمایش داده میشود"
+"subEnableRouting" = "فعالسازی مسیریابی"
+"subEnableRoutingDesc" = "تنظیمات سراسری برای فعالسازی مسیریابی در کلاینت VPN. (فقط برای Happ)"
+"subRoutingRules" = "قوانین مسیریابی"
+"subRoutingRulesDesc" = "قوانین مسیریابی سراسری برای کلاینت VPN. (فقط برای Happ)"
"subListen" = "آدرس آیپی"
"subListenDesc" = "آدرس آیپی برای سرویس سابسکریپشن. برای گوش دادن بهتمام آیپیها خالیبگذارید"
"subPort" = "پورت"
diff --git a/web/translation/translate.id_ID.toml b/web/translation/translate.id_ID.toml
index 7bd7aae0..8804ef04 100644
--- a/web/translation/translate.id_ID.toml
+++ b/web/translation/translate.id_ID.toml
@@ -374,6 +374,16 @@
"subJsonEnable" = "Aktifkan/Nonaktifkan endpoint langganan JSON secara mandiri."
"subTitle" = "Judul Langganan"
"subTitleDesc" = "Judul yang ditampilkan di klien VPN"
+"subSupportUrl" = "URL Dukungan"
+"subSupportUrlDesc" = "Tautan dukungan teknis yang ditampilkan di klien VPN"
+"subProfileUrl" = "URL Profil"
+"subProfileUrlDesc" = "Tautan ke situs web Anda yang ditampilkan di klien VPN"
+"subAnnounce" = "Pengumuman"
+"subAnnounceDesc" = "Teks pengumuman yang ditampilkan di klien VPN"
+"subEnableRouting" = "Aktifkan perutean"
+"subEnableRoutingDesc" = "Pengaturan global untuk mengaktifkan perutean (routing) di klien VPN. (Hanya untuk Happ)"
+"subRoutingRules" = "Aturan routing"
+"subRoutingRulesDesc" = "Aturan routing global untuk klien VPN. (Hanya untuk Happ)"
"subListen" = "IP Pendengar"
"subListenDesc" = "Alamat IP untuk layanan langganan. (biarkan kosong untuk mendengarkan semua IP)"
"subPort" = "Port Pendengar"
diff --git a/web/translation/translate.ja_JP.toml b/web/translation/translate.ja_JP.toml
index bc9c294a..8bba24c0 100644
--- a/web/translation/translate.ja_JP.toml
+++ b/web/translation/translate.ja_JP.toml
@@ -374,6 +374,16 @@
"subJsonEnable" = "JSON サブスクリプションのエンドポイントを個別に有効/無効にする。"
"subTitle" = "サブスクリプションタイトル"
"subTitleDesc" = "VPNクライアントに表示されるタイトル"
+"subSupportUrl" = "サポートURL"
+"subSupportUrlDesc" = "VPNクライアントに表示されるテクニカルサポートへのリンク"
+"subProfileUrl" = "プロフィールURL"
+"subProfileUrlDesc" = "VPNクライアントに表示されるWebサイトへのリンク"
+"subAnnounce" = "お知らせ"
+"subAnnounceDesc" = "VPNクライアントに表示されるお知らせのテキスト"
+"subEnableRouting" = "ルーティングを有効化"
+"subEnableRoutingDesc" = "VPNクライアントでルーティングを有効にするためのグローバル設定。(Happのみ)"
+"subRoutingRules" = "ルーティングルール"
+"subRoutingRulesDesc" = "VPNクライアントのグローバルルーティングルール。(Happのみ)"
"subListen" = "監視IP"
"subListenDesc" = "サブスクリプションサービスが監視するIPアドレス(空白にするとすべてのIPを監視)"
"subPort" = "監視ポート"
diff --git a/web/translation/translate.pt_BR.toml b/web/translation/translate.pt_BR.toml
index 86b3b97b..1b173e6e 100644
--- a/web/translation/translate.pt_BR.toml
+++ b/web/translation/translate.pt_BR.toml
@@ -374,6 +374,16 @@
"subJsonEnable" = "Ativar/Desativar o endpoint de assinatura JSON de forma independente."
"subTitle" = "Título da Assinatura"
"subTitleDesc" = "Título exibido no cliente VPN"
+"subSupportUrl" = "URL de Suporte"
+"subSupportUrlDesc" = "Link de suporte técnico exibido no cliente VPN"
+"subProfileUrl" = "URL de Perfil"
+"subProfileUrlDesc" = "Um link para o seu site exibido no cliente VPN"
+"subAnnounce" = "Anúncio"
+"subAnnounceDesc" = "O texto do anúncio exibido no cliente VPN"
+"subEnableRouting" = "Ativar roteamento"
+"subEnableRoutingDesc" = "Configuração global para habilitar o roteamento no cliente VPN. (Apenas para Happ)"
+"subRoutingRules" = "Regras de roteamento"
+"subRoutingRulesDesc" = "Regras de roteamento globais para o cliente VPN. (Apenas para Happ)"
"subListen" = "IP de Escuta"
"subListenDesc" = "O endereço IP para o serviço de assinatura. (deixe em branco para escutar em todos os IPs)"
"subPort" = "Porta de Escuta"
diff --git a/web/translation/translate.ru_RU.toml b/web/translation/translate.ru_RU.toml
index 63fbbbb6..895734f5 100644
--- a/web/translation/translate.ru_RU.toml
+++ b/web/translation/translate.ru_RU.toml
@@ -373,7 +373,17 @@
"subEnableDesc" = "Функция подписки с отдельной конфигурацией"
"subJsonEnable" = "Включить/отключить JSON-эндпоинт подписки независимо."
"subTitle" = "Заголовок подписки"
-"subTitleDesc" = "Название подписки, которое видит клиент в VPN клиенте"
+"subTitleDesc" = "Название подписки, которое видит клиент в VPN-клиенте"
+"subSupportUrl" = "URL поддержки"
+"subSupportUrlDesc" = "Ссылка на техническую поддержку, отображаемая в VPN-клиенте"
+"subProfileUrl" = "URL профиля"
+"subProfileUrlDesc" = "Ссылка на ваш сайт, отображаемая в VPN-клиенте"
+"subAnnounce" = "Объявление"
+"subAnnounceDesc" = "Текст объявления, отображаемый в VPN-клиенте"
+"subEnableRouting" = "Включить маршрутизацию"
+"subEnableRoutingDesc" = "Глобальная настройка для включения маршрутизации в VPN-клиенте. (Только для Happ)"
+"subRoutingRules" = "Правила маршрутизации"
+"subRoutingRulesDesc" = "Глобальные правила маршрутизации для VPN-клиента. (Только для Happ)"
"subListen" = "Прослушивание IP"
"subListenDesc" = "Оставьте пустым по умолчанию, чтобы отслеживать все IP-адреса"
"subPort" = "Порт подписки"
diff --git a/web/translation/translate.tr_TR.toml b/web/translation/translate.tr_TR.toml
index 25b8de9b..50639358 100644
--- a/web/translation/translate.tr_TR.toml
+++ b/web/translation/translate.tr_TR.toml
@@ -374,6 +374,16 @@
"subJsonEnable" = "JSON abonelik uç noktasını bağımsız olarak Etkinleştir/Devre Dışı bırak."
"subTitle" = "Abonelik Başlığı"
"subTitleDesc" = "VPN istemcisinde gösterilen başlık"
+"subSupportUrl" = "Destek URL'si"
+"subSupportUrlDesc" = "VPN istemcisinde gösterilen teknik destek bağlantısı"
+"subProfileUrl" = "Profil URL'si"
+"subProfileUrlDesc" = "VPN istemcisinde görüntülenen web sitenize giden bağlantı"
+"subAnnounce" = "Duyuru"
+"subAnnounceDesc" = "VPN istemcisinde görüntülenen duyuru metni"
+"subEnableRouting" = "Yönlendirmeyi etkinleştir"
+"subEnableRoutingDesc" = "VPN istemcisinde yönlendirmeyi etkinleştirmek için genel ayar. (Yalnızca Happ için)"
+"subRoutingRules" = "Yönlendirme kuralları"
+"subRoutingRulesDesc" = "VPN istemcisi için genel yönlendirme kuralları. (Yalnızca Happ için)"
"subListen" = "Dinleme IP"
"subListenDesc" = "Abonelik hizmeti için IP adresi. (tüm IP'leri dinlemek için boş bırakın)"
"subPort" = "Dinleme Portu"
diff --git a/web/translation/translate.uk_UA.toml b/web/translation/translate.uk_UA.toml
index c32854ae..54d45889 100644
--- a/web/translation/translate.uk_UA.toml
+++ b/web/translation/translate.uk_UA.toml
@@ -374,6 +374,16 @@
"subJsonEnable" = "Увімкнути/вимкнути JSON-кінець підписки незалежно."
"subTitle" = "Назва Підписки"
"subTitleDesc" = "Назва, яка відображається у VPN-клієнті"
+"subSupportUrl" = "URL підтримки"
+"subSupportUrlDesc" = "Посилання на технічну підтримку, що відображається у VPN-клієнті"
+"subProfileUrl" = "URL профілю"
+"subProfileUrlDesc" = "Посилання на ваш вебсайт, що відображається у VPN-клієнті"
+"subAnnounce" = "Оголошення"
+"subAnnounceDesc" = "Текст оголошення, що відображається у VPN-клієнті"
+"subEnableRouting" = "Увімкнути маршрутизацію"
+"subEnableRoutingDesc" = "Глобальне налаштування для увімкнення маршрутизації у VPN-клієнті. (Тільки для Happ)"
+"subRoutingRules" = "Правила маршрутизації"
+"subRoutingRulesDesc" = "Глобальні правила маршрутизації для VPN-клієнта. (Тільки для Happ)"
"subListen" = "Слухати IP"
"subListenDesc" = "IP-адреса для служби підписки. (залиште порожнім, щоб слухати всі IP-адреси)"
"subPort" = "Слухати порт"
diff --git a/web/translation/translate.vi_VN.toml b/web/translation/translate.vi_VN.toml
index 1187548e..3fa63bb1 100644
--- a/web/translation/translate.vi_VN.toml
+++ b/web/translation/translate.vi_VN.toml
@@ -374,6 +374,16 @@
"subJsonEnable" = "Bật/Tắt điểm cuối đăng ký JSON độc lập."
"subTitle" = "Tiêu đề Đăng ký"
"subTitleDesc" = "Tiêu đề hiển thị trong ứng dụng VPN"
+"subSupportUrl" = "URL Hỗ trợ"
+"subSupportUrlDesc" = "Liên kết hỗ trợ kỹ thuật hiển thị trong ứng dụng VPN"
+"subProfileUrl" = "URL Hồ sơ"
+"subProfileUrlDesc" = "Liên kết đến trang web của bạn hiển thị trong ứng dụng VPN"
+"subAnnounce" = "Thông báo"
+"subAnnounceDesc" = "Văn bản thông báo hiển thị trong ứng dụng VPN"
+"subEnableRouting" = "Bật định tuyến"
+"subEnableRoutingDesc" = "Cài đặt toàn cục để bật định tuyến trong ứng dụng khách VPN. (Chỉ dành cho Happ)"
+"subRoutingRules" = "Quy tắc định tuyến"
+"subRoutingRulesDesc" = "Quy tắc định tuyến toàn cầu cho client VPN. (Chỉ dành cho Happ)"
"subListen" = "Listening IP"
"subListenDesc" = "Mặc định để trống để nghe tất cả các IP"
"subPort" = "Cổng gói đăng ký"
diff --git a/web/translation/translate.zh_CN.toml b/web/translation/translate.zh_CN.toml
index 923cc21b..d6b82b93 100644
--- a/web/translation/translate.zh_CN.toml
+++ b/web/translation/translate.zh_CN.toml
@@ -374,6 +374,16 @@
"subJsonEnable" = "单独启用/禁用 JSON 订阅端点。"
"subTitle" = "订阅标题"
"subTitleDesc" = "在VPN客户端中显示的标题"
+"subSupportUrl" = "支持链接"
+"subSupportUrlDesc" = "VPN 客户端中显示的技术支持链接"
+"subProfileUrl" = "个人资料链接"
+"subProfileUrlDesc" = "VPN 客户端中显示的网站链接"
+"subAnnounce" = "公告"
+"subAnnounceDesc" = "VPN 客户端中显示的公告文本"
+"subEnableRouting" = "启用路由"
+"subEnableRoutingDesc" = "在 VPN 客户端中启用路由的全局设置。(僅限 Happ)"
+"subRoutingRules" = "路由規則"
+"subRoutingRulesDesc" = "VPN 用戶端的全域路由規則。(僅限 Happ)"
"subListen" = "监听 IP"
"subListenDesc" = "订阅服务监听的 IP 地址(留空表示监听所有 IP)"
"subPort" = "监听端口"
diff --git a/web/translation/translate.zh_TW.toml b/web/translation/translate.zh_TW.toml
index df32d742..616f2322 100644
--- a/web/translation/translate.zh_TW.toml
+++ b/web/translation/translate.zh_TW.toml
@@ -374,6 +374,16 @@
"subJsonEnable" = "獨立啟用/停用 JSON 訂閱端點。"
"subTitle" = "訂閱標題"
"subTitleDesc" = "在VPN客戶端中顯示的標題"
+"subSupportUrl" = "支援連結"
+"subSupportUrlDesc" = "VPN 用戶端中顯示的技術支援連結"
+"subProfileUrl" = "個人資料連結"
+"subProfileUrlDesc" = "VPN 用戶端中顯示的網站連結"
+"subAnnounce" = "公告"
+"subAnnounceDesc" = "VPN 用戶端中顯示的公告文字"
+"subEnableRouting" = "啟用路由"
+"subEnableRoutingDesc" = "在 VPN 用戶端中啟用路由的全域設定。(僅限 Happ)"
+"subRoutingRules" = "路由規則"
+"subRoutingRulesDesc" = "VPN 用戶端的全域路由規則。(僅限 Happ)"
"subListen" = "監聽 IP"
"subListenDesc" = "訂閱服務監聽的 IP 地址(留空表示監聽所有 IP)"
"subPort" = "監聽埠"