diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini
index d825e47a76..451742ac06 100644
--- a/custom/conf/app.example.ini
+++ b/custom/conf/app.example.ini
@@ -1,10 +1,10 @@
-; This file lists the default values used by Gitea
+; This file lists the default values used by Forgejo
 ;; Copy required sections to your own app.ini (default is custom/conf/app.ini)
 ;; and modify as needed.
 ;; Do not copy the whole file as-is, as it contains some invalid sections for illustrative purposes.
 ;; If you don't know what a setting is you should not set it.
 ;;
-;; see https://docs.gitea.com/administration/config-cheat-sheet for additional documentation.
+;; see https://forgejo.org/docs/next/admin/config-cheat-sheet for additional documentation.
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -41,7 +41,14 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;
 ;; App name that shows in every page title
-APP_NAME = ; Gitea: Git with a cup of tea
+APP_NAME = ; Forgejo: Beyond coding. We Forge.
+;;
+;; APP_SLOGAN shows a slogan near the App name in every page title.
+;APP_SLOGAN =
+;;
+;; APP_DISPLAY_NAME_FORMAT defines how the AppDisplayName should be presented
+;; It is used only if APP_SLOGAN is set.
+;APP_DISPLAY_NAME_FORMAT = {APP_NAME}: {APP_SLOGAN}
 ;;
 ;; RUN_USER will automatically detect the current user - but you can set it here change it if you run locally
 RUN_USER = ; git
diff --git a/modules/setting/server.go b/modules/setting/server.go
index c20dd1949d..5cc33f6fc4 100644
--- a/modules/setting/server.go
+++ b/modules/setting/server.go
@@ -45,6 +45,14 @@ var (
 	// AppName is the Application name, used in the page title.
 	// It maps to ini:"APP_NAME"
 	AppName string
+	// AppSlogan is the Application slogan.
+	// It maps to ini:"APP_SLOGAN"
+	AppSlogan string
+	// AppDisplayNameFormat defines how the AppDisplayName should be presented
+	// It maps to ini:"APP_DISPLAY_NAME_FORMAT"
+	AppDisplayNameFormat string
+	// AppDisplayName is the display name for the application, defined following AppDisplayNameFormat
+	AppDisplayName string
 	// AppURL is the Application ROOT_URL. It always has a '/' suffix
 	// It maps to ini:"ROOT_URL"
 	AppURL string
@@ -164,10 +172,21 @@ func MakeAbsoluteAssetURL(appURL, staticURLPrefix string) string {
 	return strings.TrimSuffix(staticURLPrefix, "/")
 }
 
+func generateDisplayName() string {
+	appDisplayName := AppName
+	if AppSlogan != "" {
+		appDisplayName = strings.Replace(AppDisplayNameFormat, "{APP_NAME}", AppName, 1)
+		appDisplayName = strings.Replace(appDisplayName, "{APP_SLOGAN}", AppSlogan, 1)
+	}
+	return appDisplayName
+}
+
 func loadServerFrom(rootCfg ConfigProvider) {
 	sec := rootCfg.Section("server")
 	AppName = rootCfg.Section("").Key("APP_NAME").MustString("Forgejo: Beyond coding. We Forge.")
-
+	AppSlogan = rootCfg.Section("").Key("APP_SLOGAN").MustString("")
+	AppDisplayNameFormat = rootCfg.Section("").Key("APP_DISPLAY_NAME_FORMAT").MustString("{APP_NAME}: {APP_SLOGAN}")
+	AppDisplayName = generateDisplayName()
 	Domain = sec.Key("DOMAIN").MustString("localhost")
 	HTTPAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
 	HTTPPort = sec.Key("HTTP_PORT").MustString("3000")
diff --git a/modules/setting/server_test.go b/modules/setting/server_test.go
new file mode 100644
index 0000000000..8db8168854
--- /dev/null
+++ b/modules/setting/server_test.go
@@ -0,0 +1,36 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package setting
+
+import (
+	"testing"
+
+	"code.gitea.io/gitea/modules/test"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestDisplayNameDefault(t *testing.T) {
+	defer test.MockVariableValue(&AppName, "Forgejo")()
+	defer test.MockVariableValue(&AppSlogan, "Beyond coding. We Forge.")()
+	defer test.MockVariableValue(&AppDisplayNameFormat, "{APP_NAME}: {APP_SLOGAN}")()
+	displayName := generateDisplayName()
+	assert.Equal(t, "Forgejo: Beyond coding. We Forge.", displayName)
+}
+
+func TestDisplayNameEmptySlogan(t *testing.T) {
+	defer test.MockVariableValue(&AppName, "Forgejo")()
+	defer test.MockVariableValue(&AppSlogan, "")()
+	defer test.MockVariableValue(&AppDisplayNameFormat, "{APP_NAME}: {APP_SLOGAN}")()
+	displayName := generateDisplayName()
+	assert.Equal(t, "Forgejo", displayName)
+}
+
+func TestDisplayNameCustomFormat(t *testing.T) {
+	defer test.MockVariableValue(&AppName, "Forgejo")()
+	defer test.MockVariableValue(&AppSlogan, "Beyond coding. We Forge.")()
+	defer test.MockVariableValue(&AppDisplayNameFormat, "{APP_NAME} - {APP_SLOGAN}")()
+	displayName := generateDisplayName()
+	assert.Equal(t, "Forgejo - Beyond coding. We Forge.", displayName)
+}
diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index 4dc1f1938c..f1ae1c8bb1 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -79,6 +79,12 @@ func NewFuncMap() template.FuncMap {
 		"AppName": func() string {
 			return setting.AppName
 		},
+		"AppSlogan": func() string {
+			return setting.AppSlogan
+		},
+		"AppDisplayName": func() string {
+			return setting.AppDisplayName
+		},
 		"AppSubUrl": func() string {
 			return setting.AppSubURL
 		},
diff --git a/modules/templates/mailer.go b/modules/templates/mailer.go
index 7c97e1ea89..ee79755dbb 100644
--- a/modules/templates/mailer.go
+++ b/modules/templates/mailer.go
@@ -28,6 +28,12 @@ func mailSubjectTextFuncMap() texttmpl.FuncMap {
 		"AppName": func() string {
 			return setting.AppName
 		},
+		"AppSlogan": func() string {
+			return setting.AppSlogan
+		},
+		"AppDisplayName": func() string {
+			return setting.AppDisplayName
+		},
 		"AppDomain": func() string { // documented in mail-templates.md
 			return setting.Domain
 		},
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 13adb33a55..39f7886c54 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -267,6 +267,8 @@ err_admin_name_is_invalid = Administrator Username is invalid
 general_title = General settings
 app_name = Instance title
 app_name_helper = You can enter your company name here.
+app_slogan = Instance slogan
+app_slogan_helper = Enter your instance slogan here. Leave empty to disable.
 repo_path = Repository root path
 repo_path_helper = Remote Git repositories will be saved to this directory.
 lfs_path = Git LFS root path
@@ -3207,6 +3209,7 @@ auths.invalid_openIdConnectAutoDiscoveryURL = Invalid Auto Discovery URL (this m
 
 config.server_config = Server configuration
 config.app_name = Instance title
+config.app_slogan = Instance slogan
 config.app_ver = Forgejo version
 config.app_url = Base URL
 config.custom_conf = Configuration file path
diff --git a/release-notes/8.0.0/3616.md b/release-notes/8.0.0/3616.md
new file mode 100644
index 0000000000..fdeb470cf0
--- /dev/null
+++ b/release-notes/8.0.0/3616.md
@@ -0,0 +1,10 @@
+There are a couple of new configs to define the name of the instance.
+The more important is `APP_SLOGAN`. It permits to configure a slogan for the site and it is optional.
+The other is `APP_DISPLAY_NAME_FORMAT` and permits to customize the aspect of the full display name for the instance used in some parts of the UI as:
+
+- Title page.
+- Homepage head title.
+- Open Graph site and title meta tags.
+
+Its default value is `APP_NAME: APP_SLOGAN`.
+The config `APP_DISPLAY_NAME_FORMAT` is used only if `APP_SLOGAN` is set otherwise the full display name shows only `APP_NAME` value.
diff --git a/routers/install/install.go b/routers/install/install.go
index 8f4fafa6f5..dfd8047d04 100644
--- a/routers/install/install.go
+++ b/routers/install/install.go
@@ -115,7 +115,8 @@ func Install(ctx *context.Context) {
 	ctx.Data["CurDbType"] = curDBType
 
 	// Application general settings
-	form.AppName = setting.AppName
+	form.AppName = "Forgejo"
+	form.AppSlogan = "Beyond coding. We Forge."
 	form.RepoRootPath = setting.RepoRootPath
 	form.LFSRootPath = setting.LFS.Storage.Path
 
@@ -383,6 +384,7 @@ func SubmitInstall(ctx *context.Context) {
 	}
 
 	cfg.Section("").Key("APP_NAME").SetValue(form.AppName)
+	cfg.Section("").Key("APP_SLOGAN").SetValue(form.AppSlogan)
 	cfg.Section("").Key("RUN_USER").SetValue(form.RunUser)
 	cfg.Section("").Key("WORK_PATH").SetValue(setting.AppWorkPath)
 	cfg.Section("").Key("RUN_MODE").SetValue("prod")
diff --git a/services/forms/user_form.go b/services/forms/user_form.go
index 0b7bea4638..cc93b27e2a 100644
--- a/services/forms/user_form.go
+++ b/services/forms/user_form.go
@@ -31,6 +31,7 @@ type InstallForm struct {
 	DbSchema string
 
 	AppName      string `binding:"Required" locale:"install.app_name"`
+	AppSlogan    string
 	RepoRootPath string `binding:"Required"`
 	LFSRootPath  string
 	RunUser      string `binding:"Required"`
diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl
index 1e94935a16..d4e5b326fd 100644
--- a/templates/admin/config.tmpl
+++ b/templates/admin/config.tmpl
@@ -7,6 +7,8 @@
 			<dl class="admin-dl-horizontal">
 				<dt>{{ctx.Locale.Tr "admin.config.app_name"}}</dt>
 				<dd>{{AppName}}</dd>
+				<dt>{{ctx.Locale.Tr "admin.config.app_slogan"}}</dt>
+				<dd>{{AppSlogan}}</dd>
 				<dt>{{ctx.Locale.Tr "admin.config.app_ver"}}</dt>
 				<dd>{{AppVer}}{{.AppBuiltWith}}</dd>
 				<dt>{{ctx.Locale.Tr "admin.config.custom_conf"}}</dt>
diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl
index c0caf34d53..7753f49243 100644
--- a/templates/base/head.tmpl
+++ b/templates/base/head.tmpl
@@ -3,7 +3,7 @@
 <head>
 	<meta name="viewport" content="width=device-width, initial-scale=1">
 	{{/* Display `- .Repository.FullName` only if `.Title` does not already start with that. */}}
-	<title>{{if .Title}}{{.Title}} - {{end}}{{if and (.Repository.Name) (not (StringUtils.HasPrefix .Title .Repository.FullName))}}{{.Repository.FullName}} - {{end}}{{AppName}}</title>
+	<title>{{if .Title}}{{.Title}} - {{end}}{{if and (.Repository.Name) (not (StringUtils.HasPrefix .Title .Repository.FullName))}}{{.Repository.FullName}} - {{end}}{{AppDisplayName}}</title>
 	{{if .ManifestData}}<link rel="manifest" href="data:{{.ManifestData}}">{{end}}
 	<meta name="author" content="{{if .Repository}}{{.Owner.Name}}{{else}}{{MetaAuthor}}{{end}}">
 	<meta name="description" content="{{if .Repository}}{{.Repository.Name}}{{if .Repository.Description}} - {{.Repository.Description}}{{end}}{{else}}{{MetaDescription}}{{end}}">
diff --git a/templates/base/head_opengraph.tmpl b/templates/base/head_opengraph.tmpl
index f1f38999d2..c02adabaab 100644
--- a/templates/base/head_opengraph.tmpl
+++ b/templates/base/head_opengraph.tmpl
@@ -38,10 +38,10 @@
 		<meta property="og:image" content="{{.Repository.Owner.AvatarLink ctx}}">
 	{{end}}
 {{else}}
-	<meta property="og:title" content="{{AppName}}">
+	<meta property="og:title" content="{{AppDisplayName}}">
 	<meta property="og:type" content="website">
 	<meta property="og:image" content="{{AssetUrlPrefix}}/img/logo.png">
 	<meta property="og:url" content="{{AppUrl}}">
 	<meta property="og:description" content="{{MetaDescription}}">
 {{end}}
-<meta property="og:site_name" content="{{AppName}}">
+<meta property="og:site_name" content="{{AppDisplayName}}">
diff --git a/templates/home.tmpl b/templates/home.tmpl
index e6fd4ef020..23b1feae21 100644
--- a/templates/home.tmpl
+++ b/templates/home.tmpl
@@ -5,7 +5,7 @@
 			<img class="logo" width="220" height="220" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{ctx.Locale.Tr "logo"}}">
 			<div class="hero">
 				<h1 class="ui icon header title">
-					{{AppName}}
+					{{AppDisplayName}}
 				</h1>
 				<h2>{{ctx.Locale.Tr "startpage.app_desc"}}</h2>
 			</div>
diff --git a/templates/install.tmpl b/templates/install.tmpl
index f027b47922..29eb44526a 100644
--- a/templates/install.tmpl
+++ b/templates/install.tmpl
@@ -107,6 +107,11 @@
 						<input id="app_name" name="app_name" value="{{.app_name}}" required>
 						<span class="help">{{ctx.Locale.Tr "install.app_name_helper"}}</span>
 					</div>
+					<div class="inline field">
+						<label for="app_slogan">{{ctx.Locale.Tr "install.app_slogan"}}</label>
+						<input id="app_slogan" name="app_slogan" value="{{.app_slogan}}">
+						<span class="help">{{ctx.Locale.Tr "install.app_slogan_helper"}}</span>
+					</div>
 					<div class="inline required field {{if .Err_RepoRootPath}}error{{end}}">
 						<label for="repo_root_path">{{ctx.Locale.Tr "install.repo_path"}}</label>
 						<input id="repo_root_path" name="repo_root_path" value="{{.repo_root_path}}" required>
diff --git a/templates/status/500.tmpl b/templates/status/500.tmpl
index 8e250abe27..e5fdaec0cf 100644
--- a/templates/status/500.tmpl
+++ b/templates/status/500.tmpl
@@ -9,7 +9,7 @@
 <html lang="{{ctx.Locale.Lang}}" data-theme="{{ThemeName .SignedUser}}">
 <head>
 	<meta name="viewport" content="width=device-width, initial-scale=1">
-	<title>{{ctx.Locale.Tr "error.server_internal"}} - {{AppName}}</title>
+	<title>{{ctx.Locale.Tr "error.server_internal"}} - {{AppDisplayName}}</title>
 	<link rel="icon" href="{{AssetUrlPrefix}}/img/favicon.svg" type="image/svg+xml">
 	<link rel="alternate icon" href="{{AssetUrlPrefix}}/img/favicon.png" type="image/png">
 	{{template "base/head_style" .}}
diff --git a/tests/integration/view_test.go b/tests/integration/view_test.go
index e77cc382e9..d7225101d7 100644
--- a/tests/integration/view_test.go
+++ b/tests/integration/view_test.go
@@ -185,3 +185,28 @@ func TestInHistoryButton(t *testing.T) {
 		})
 	})
 }
+
+func TestTitleDisplayName(t *testing.T) {
+	session := emptyTestSession(t)
+	title := GetHTMLTitle(t, session, "/")
+	assert.Equal(t, "Gitea: Git with a cup of tea", title)
+}
+
+func TestHomeDisplayName(t *testing.T) {
+	session := emptyTestSession(t)
+	req := NewRequest(t, "GET", "/")
+	resp := session.MakeRequest(t, req, http.StatusOK)
+	htmlDoc := NewHTMLParser(t, resp.Body)
+	assert.Equal(t, "Gitea: Git with a cup of tea", strings.TrimSpace(htmlDoc.Find("h1.title").Text()))
+}
+
+func TestOpenGraphDisplayName(t *testing.T) {
+	session := emptyTestSession(t)
+	req := NewRequest(t, "GET", "/")
+	resp := session.MakeRequest(t, req, http.StatusOK)
+	htmlDoc := NewHTMLParser(t, resp.Body)
+	ogTitle, _ := htmlDoc.Find("meta[property='og:title']").Attr("content")
+	assert.Equal(t, "Gitea: Git with a cup of tea", ogTitle)
+	ogSiteName, _ := htmlDoc.Find("meta[property='og:site_name']").Attr("content")
+	assert.Equal(t, "Gitea: Git with a cup of tea", ogSiteName)
+}
diff --git a/tests/mysql.ini.tmpl b/tests/mysql.ini.tmpl
index ab2e91ebdb..1bfc797ba5 100644
--- a/tests/mysql.ini.tmpl
+++ b/tests/mysql.ini.tmpl
@@ -1,4 +1,5 @@
-APP_NAME = Gitea: Git with a cup of tea
+APP_NAME = Gitea
+APP_SLOGAN = Git with a cup of tea
 RUN_MODE = prod
 
 [database]
diff --git a/tests/pgsql.ini.tmpl b/tests/pgsql.ini.tmpl
index 300d36eb71..760826280b 100644
--- a/tests/pgsql.ini.tmpl
+++ b/tests/pgsql.ini.tmpl
@@ -1,4 +1,5 @@
-APP_NAME = Gitea: Git with a cup of tea
+APP_NAME = Gitea
+APP_SLOGAN = Git with a cup of tea
 RUN_MODE = prod
 
 [database]
diff --git a/tests/sqlite.ini.tmpl b/tests/sqlite.ini.tmpl
index bc7227fcc9..48ee8d4e4a 100644
--- a/tests/sqlite.ini.tmpl
+++ b/tests/sqlite.ini.tmpl
@@ -1,4 +1,5 @@
-APP_NAME = Gitea: Git with a cup of tea
+APP_NAME = Gitea
+APP_SLOGAN = Git with a cup of tea
 RUN_MODE = prod
 
 [database]