diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini
index 7c7a43944f..0c76bbc6cd 100644
--- a/custom/conf/app.example.ini
+++ b/custom/conf/app.example.ini
@@ -907,6 +907,24 @@ LEVEL = Info
 ;; Valid site url schemes for user profiles
 ;VALID_SITE_URL_SCHEMES=http,https
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;[service.explore]
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Only allow signed in users to view the explore pages.
+;REQUIRE_SIGNIN_VIEW = false
+;;
+;; Disable the users explore page.
+;DISABLE_USERS_PAGE = false
+;;
+;; Disable the organizations explore page.
+;DISABLE_ORGANIZATIONS_PAGE = false
+;;
+;; Disable the code explore page.
+;DISABLE_CODE_PAGE = false
+;;
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/modules/setting/service.go b/modules/setting/service.go
index 3ea1501236..c858f80354 100644
--- a/modules/setting/service.go
+++ b/modules/setting/service.go
@@ -90,8 +90,10 @@ var Service = struct {
 
 	// Explore page settings
 	Explore struct {
-		RequireSigninView bool `ini:"REQUIRE_SIGNIN_VIEW"`
-		DisableUsersPage  bool `ini:"DISABLE_USERS_PAGE"`
+		RequireSigninView        bool `ini:"REQUIRE_SIGNIN_VIEW"`
+		DisableUsersPage         bool `ini:"DISABLE_USERS_PAGE"`
+		DisableOrganizationsPage bool `ini:"DISABLE_ORGANIZATIONS_PAGE"`
+		DisableCodePage          bool `ini:"DISABLE_CODE_PAGE"`
 	} `ini:"service.explore"`
 }{
 	AllowedUserVisibilityModesSlice: []bool{true, true, true},
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 883e694e44..bfc601c835 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -356,12 +356,20 @@ func reqToken() func(ctx *context.APIContext) {
 
 func reqExploreSignIn() func(ctx *context.APIContext) {
 	return func(ctx *context.APIContext) {
-		if setting.Service.Explore.RequireSigninView && !ctx.IsSigned {
+		if (setting.Service.RequireSignInView || setting.Service.Explore.RequireSigninView) && !ctx.IsSigned {
 			ctx.Error(http.StatusUnauthorized, "reqExploreSignIn", "you must be signed in to search for users")
 		}
 	}
 }
 
+func reqUsersExploreEnabled() func(ctx *context.APIContext) {
+	return func(ctx *context.APIContext) {
+		if setting.Service.Explore.DisableUsersPage {
+			ctx.NotFound()
+		}
+	}
+}
+
 func reqBasicOrRevProxyAuth() func(ctx *context.APIContext) {
 	return func(ctx *context.APIContext) {
 		if ctx.IsSigned && setting.Service.EnableReverseProxyAuthAPI && ctx.Data["AuthedMethod"].(string) == auth.ReverseProxyMethodName {
@@ -955,7 +963,7 @@ func Routes() *web.Router {
 
 		// Users (requires user scope)
 		m.Group("/users", func() {
-			m.Get("/search", reqExploreSignIn(), user.Search)
+			m.Get("/search", reqExploreSignIn(), reqUsersExploreEnabled(), user.Search)
 
 			m.Group("/{username}", func() {
 				m.Get("", reqExploreSignIn(), user.GetInfo)
diff --git a/routers/web/explore/code.go b/routers/web/explore/code.go
index ecd7c33e01..48f890332b 100644
--- a/routers/web/explore/code.go
+++ b/routers/web/explore/code.go
@@ -21,12 +21,13 @@ const (
 
 // Code render explore code page
 func Code(ctx *context.Context) {
-	if !setting.Indexer.RepoIndexerEnabled {
+	if !setting.Indexer.RepoIndexerEnabled || setting.Service.Explore.DisableCodePage {
 		ctx.Redirect(setting.AppSubURL + "/explore")
 		return
 	}
 
-	ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage
+	ctx.Data["UsersPageIsDisabled"] = setting.Service.Explore.DisableUsersPage
+	ctx.Data["OrganizationsPageIsDisabled"] = setting.Service.Explore.DisableOrganizationsPage
 	ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
 	ctx.Data["Title"] = ctx.Tr("explore")
 	ctx.Data["PageIsExplore"] = true
diff --git a/routers/web/explore/org.go b/routers/web/explore/org.go
index f8fd6ec38e..7178630b64 100644
--- a/routers/web/explore/org.go
+++ b/routers/web/explore/org.go
@@ -14,7 +14,13 @@ import (
 
 // Organizations render explore organizations page
 func Organizations(ctx *context.Context) {
-	ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage
+	if setting.Service.Explore.DisableOrganizationsPage {
+		ctx.Redirect(setting.AppSubURL + "/explore")
+		return
+	}
+
+	ctx.Data["UsersPageIsDisabled"] = setting.Service.Explore.DisableUsersPage
+	ctx.Data["CodePageIsDisabled"] = setting.Service.Explore.DisableCodePage
 	ctx.Data["Title"] = ctx.Tr("explore")
 	ctx.Data["PageIsExplore"] = true
 	ctx.Data["PageIsExploreOrganizations"] = true
diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go
index 62090e5bf4..5b6f612e72 100644
--- a/routers/web/explore/repo.go
+++ b/routers/web/explore/repo.go
@@ -165,7 +165,9 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
 
 // Repos render explore repositories page
 func Repos(ctx *context.Context) {
-	ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage
+	ctx.Data["UsersPageIsDisabled"] = setting.Service.Explore.DisableUsersPage
+	ctx.Data["OrganizationsPageIsDisabled"] = setting.Service.Explore.DisableOrganizationsPage
+	ctx.Data["CodePageIsDisabled"] = setting.Service.Explore.DisableCodePage
 	ctx.Data["Title"] = ctx.Tr("explore")
 	ctx.Data["PageIsExplore"] = true
 	ctx.Data["PageIsExploreRepositories"] = true
diff --git a/routers/web/explore/user.go b/routers/web/explore/user.go
index 18337aff48..5f6b8fcee6 100644
--- a/routers/web/explore/user.go
+++ b/routers/web/explore/user.go
@@ -131,9 +131,11 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions,
 // Users render explore users page
 func Users(ctx *context.Context) {
 	if setting.Service.Explore.DisableUsersPage {
-		ctx.Redirect(setting.AppSubURL + "/explore/repos")
+		ctx.Redirect(setting.AppSubURL + "/explore")
 		return
 	}
+	ctx.Data["OrganizationsPageIsDisabled"] = setting.Service.Explore.DisableOrganizationsPage
+	ctx.Data["CodePageIsDisabled"] = setting.Service.Explore.DisableCodePage
 	ctx.Data["Title"] = ctx.Tr("explore")
 	ctx.Data["PageIsExplore"] = true
 	ctx.Data["PageIsExploreUsers"] = true
diff --git a/routers/web/user/search.go b/routers/web/user/search.go
index fb7729bbe1..be5eee90a9 100644
--- a/routers/web/user/search.go
+++ b/routers/web/user/search.go
@@ -8,37 +8,24 @@ import (
 
 	"code.gitea.io/gitea/models/db"
 	user_model "code.gitea.io/gitea/models/user"
+	"code.gitea.io/gitea/modules/optional"
+	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/services/context"
 	"code.gitea.io/gitea/services/convert"
 )
 
-// Search search users
-func Search(ctx *context.Context) {
-	listOptions := db.ListOptions{
-		Page:     ctx.FormInt("page"),
-		PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
-	}
-
-	users, maxResults, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
+// SearchCandidates searches candidate users for dropdown list
+func SearchCandidates(ctx *context.Context) {
+	users, _, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
 		Actor:       ctx.Doer,
 		Keyword:     ctx.FormTrim("q"),
-		UID:         ctx.FormInt64("uid"),
 		Type:        user_model.UserTypeIndividual,
-		IsActive:    ctx.FormOptionalBool("active"),
-		ListOptions: listOptions,
+		IsActive:    optional.Some(true),
+		ListOptions: db.ListOptions{PageSize: setting.UI.MembersPagingNum},
 	})
 	if err != nil {
-		ctx.JSON(http.StatusInternalServerError, map[string]any{
-			"ok":    false,
-			"error": err.Error(),
-		})
+		ctx.ServerError("Unable to search users", err)
 		return
 	}
-
-	ctx.SetTotalCountHeader(maxResults)
-
-	ctx.JSON(http.StatusOK, map[string]any{
-		"ok":   true,
-		"data": convert.ToUsers(ctx, ctx.Doer, users),
-	})
+	ctx.JSON(http.StatusOK, map[string]any{"data": convert.ToUsers(ctx, ctx.Doer, users)})
 }
diff --git a/routers/web/web.go b/routers/web/web.go
index f28ec82c8f..a6ccb7a792 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -670,7 +670,7 @@ func registerRoutes(m *web.Router) {
 		m.Post("/forgot_password", auth.ForgotPasswdPost)
 		m.Post("/logout", auth.SignOut)
 		m.Get("/stopwatches", reqSignIn, user.GetStopwatches)
-		m.Get("/search", ignExploreSignIn, user.Search)
+		m.Get("/search_candidates", ignExploreSignIn, user.SearchCandidates)
 		m.Group("/oauth2", func() {
 			m.Get("/{provider}", auth.SignInOAuth)
 			m.Get("/{provider}/callback", auth.SignInOAuthCallback)
diff --git a/templates/explore/navbar.tmpl b/templates/explore/navbar.tmpl
index a157cd4b75..6b595af63a 100644
--- a/templates/explore/navbar.tmpl
+++ b/templates/explore/navbar.tmpl
@@ -3,15 +3,17 @@
 		<a class="{{if .PageIsExploreRepositories}}active {{end}}item" href="{{AppSubUrl}}/explore/repos">
 			{{svg "octicon-repo"}} {{ctx.Locale.Tr "explore.repos"}}
 		</a>
-		{{if not .UsersIsDisabled}}
+		{{if not .UsersPageIsDisabled}}
 			<a class="{{if .PageIsExploreUsers}}active {{end}}item" href="{{AppSubUrl}}/explore/users">
 				{{svg "octicon-person"}} {{ctx.Locale.Tr "explore.users"}}
 			</a>
 		{{end}}
+		{{if not .OrganizationsPageIsDisabled}}
 		<a class="{{if .PageIsExploreOrganizations}}active {{end}}item" href="{{AppSubUrl}}/explore/organizations">
 			{{svg "octicon-organization"}} {{ctx.Locale.Tr "explore.organizations"}}
 		</a>
-		{{if and (not ctx.Consts.RepoUnitTypeCode.UnitGlobalDisabled) .IsRepoIndexerEnabled}}
+		{{end}}
+		{{if and (not ctx.Consts.RepoUnitTypeCode.UnitGlobalDisabled) .IsRepoIndexerEnabled (not .CodePageIsDisabled)}}
 		<a class="{{if .PageIsExploreCode}}active {{end}}item" href="{{AppSubUrl}}/explore/code">
 			{{svg "octicon-code"}} {{ctx.Locale.Tr "explore.code"}}
 		</a>
diff --git a/web_src/js/features/comp/SearchUserBox.ts b/web_src/js/features/comp/SearchUserBox.ts
index 7ef23fe4b0..ceb756b557 100644
--- a/web_src/js/features/comp/SearchUserBox.ts
+++ b/web_src/js/features/comp/SearchUserBox.ts
@@ -8,41 +8,38 @@ export function initCompSearchUserBox() {
   const searchUserBox = document.querySelector('#search-user-box');
   if (!searchUserBox) return;
 
-  const $searchUserBox = $(searchUserBox);
   const allowEmailInput = searchUserBox.getAttribute('data-allow-email') === 'true';
   const allowEmailDescription = searchUserBox.getAttribute('data-allow-email-description') ?? undefined;
-  $searchUserBox.search({
+  $(searchUserBox).search({
     minCharacters: 2,
     apiSettings: {
-      url: `${appSubUrl}/user/search?active=1&q={query}`,
+      url: `${appSubUrl}/user/search_candidates?q={query}`,
       onResponse(response) {
-        const items = [];
-        const searchQuery = $searchUserBox.find('input').val();
+        const resultItems = [];
+        const searchQuery = searchUserBox.querySelector('input').value;
         const searchQueryUppercase = searchQuery.toUpperCase();
-        $.each(response.data, (_i, item) => {
+        for (const item of response.data) {
           const resultItem = {
             title: item.login,
             image: item.avatar_url,
+            description: htmlEscape(item.full_name),
           };
-          if (item.full_name) {
-            resultItem.description = htmlEscape(item.full_name);
-          }
           if (searchQueryUppercase === item.login.toUpperCase()) {
-            items.unshift(resultItem);
+            resultItems.unshift(resultItem); // add the exact match to the top
           } else {
-            items.push(resultItem);
+            resultItems.push(resultItem);
           }
-        });
+        }
 
-        if (allowEmailInput && !items.length && looksLikeEmailAddressCheck.test(searchQuery)) {
+        if (allowEmailInput && !resultItems.length && looksLikeEmailAddressCheck.test(searchQuery)) {
           const resultItem = {
             title: searchQuery,
             description: allowEmailDescription,
           };
-          items.push(resultItem);
+          resultItems.push(resultItem);
         }
 
-        return {results: items};
+        return {results: resultItems};
       },
     },
     searchFields: ['login', 'full_name'],