diff --git a/docs/guides/images/ui-customization/account-console-with-avatar.png b/docs/guides/images/ui-customization/account-console-with-avatar.png
new file mode 100644
index 00000000000..9b22807101c
Binary files /dev/null and b/docs/guides/images/ui-customization/account-console-with-avatar.png differ
diff --git a/docs/guides/images/ui-customization/avatar-validation.png b/docs/guides/images/ui-customization/avatar-validation.png
new file mode 100644
index 00000000000..f6e1bfffc06
Binary files /dev/null and b/docs/guides/images/ui-customization/avatar-validation.png differ
diff --git a/docs/guides/images/ui-customization/color-chooser.png b/docs/guides/images/ui-customization/color-chooser.png
new file mode 100644
index 00000000000..da720917a54
Binary files /dev/null and b/docs/guides/images/ui-customization/color-chooser.png differ
diff --git a/docs/guides/images/ui-customization/custom-account-console.png b/docs/guides/images/ui-customization/custom-account-console.png
new file mode 100644
index 00000000000..d7a1b459f1d
Binary files /dev/null and b/docs/guides/images/ui-customization/custom-account-console.png differ
diff --git a/docs/guides/images/ui-customization/device-activity-after.png b/docs/guides/images/ui-customization/device-activity-after.png
new file mode 100644
index 00000000000..6f30d91af83
Binary files /dev/null and b/docs/guides/images/ui-customization/device-activity-after.png differ
diff --git a/docs/guides/images/ui-customization/device-activity-before.png b/docs/guides/images/ui-customization/device-activity-before.png
new file mode 100644
index 00000000000..2f87d87ac46
Binary files /dev/null and b/docs/guides/images/ui-customization/device-activity-before.png differ
diff --git a/docs/guides/images/ui-customization/easy-theme-find-color.png b/docs/guides/images/ui-customization/easy-theme-find-color.png
new file mode 100644
index 00000000000..2fca430aef3
Binary files /dev/null and b/docs/guides/images/ui-customization/easy-theme-find-color.png differ
diff --git a/docs/guides/images/ui-customization/empty-user-federation-page.png b/docs/guides/images/ui-customization/empty-user-federation-page.png
new file mode 100644
index 00000000000..5576a174f90
Binary files /dev/null and b/docs/guides/images/ui-customization/empty-user-federation-page.png differ
diff --git a/docs/guides/images/ui-customization/keycloak_logo.png b/docs/guides/images/ui-customization/keycloak_logo.png
new file mode 100644
index 00000000000..4883f523023
Binary files /dev/null and b/docs/guides/images/ui-customization/keycloak_logo.png differ
diff --git a/docs/guides/images/ui-customization/login-sunrise.png b/docs/guides/images/ui-customization/login-sunrise.png
new file mode 100644
index 00000000000..6879b1f438f
Binary files /dev/null and b/docs/guides/images/ui-customization/login-sunrise.png differ
diff --git a/docs/guides/images/ui-customization/myPage.png b/docs/guides/images/ui-customization/myPage.png
new file mode 100644
index 00000000000..040ed44758c
Binary files /dev/null and b/docs/guides/images/ui-customization/myPage.png differ
diff --git a/docs/guides/images/ui-customization/picture-attribute-general-settings.png b/docs/guides/images/ui-customization/picture-attribute-general-settings.png
new file mode 100644
index 00000000000..5e203aab983
Binary files /dev/null and b/docs/guides/images/ui-customization/picture-attribute-general-settings.png differ
diff --git a/docs/guides/images/ui-customization/quick-theme-overview.png b/docs/guides/images/ui-customization/quick-theme-overview.png
new file mode 100644
index 00000000000..90e67add746
Binary files /dev/null and b/docs/guides/images/ui-customization/quick-theme-overview.png differ
diff --git a/docs/guides/images/ui-customization/readonly-user-storage-provider-with-config.png b/docs/guides/images/ui-customization/readonly-user-storage-provider-with-config.png
new file mode 100644
index 00000000000..68e71937da0
Binary files /dev/null and b/docs/guides/images/ui-customization/readonly-user-storage-provider-with-config.png differ
diff --git a/docs/guides/images/ui-customization/simple-quick-theme-changes.png b/docs/guides/images/ui-customization/simple-quick-theme-changes.png
new file mode 100644
index 00000000000..367df066e0e
Binary files /dev/null and b/docs/guides/images/ui-customization/simple-quick-theme-changes.png differ
diff --git a/docs/guides/images/ui-customization/storage-provider-created.png b/docs/guides/images/ui-customization/storage-provider-created.png
new file mode 100644
index 00000000000..7e5757ce8cb
Binary files /dev/null and b/docs/guides/images/ui-customization/storage-provider-created.png differ
diff --git a/docs/guides/images/ui-customization/user-federation-page.png b/docs/guides/images/ui-customization/user-federation-page.png
new file mode 100644
index 00000000000..787eb9e08af
Binary files /dev/null and b/docs/guides/images/ui-customization/user-federation-page.png differ
diff --git a/docs/guides/pom.xml b/docs/guides/pom.xml
index dde0fa3350a..9dbf7330f26 100644
--- a/docs/guides/pom.xml
+++ b/docs/guides/pom.xml
@@ -14,8 +14,9 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-
+
keycloak-docs-parent
org.keycloak
@@ -28,7 +29,8 @@
Keycloak Guides
keycloak-guides
Keycloak Guides
-
+
jar
@@ -133,7 +135,7 @@
left
font
true
-
+
-
true
../images
@@ -198,7 +200,8 @@
${basedir}/target/generated-guides/getting-started
- ${project.build.directory}/generated-docs/getting-started
+
+ ${project.build.directory}/generated-docs/getting-started
@@ -209,7 +212,8 @@
${basedir}/target/generated-guides/high-availability
- ${project.build.directory}/generated-docs/high-availability
+
+ ${project.build.directory}/generated-docs/high-availability
@@ -224,6 +228,19 @@
true
+
+ ui-customization-asciidoc-to-html
+ generate-resources
+
+ process-asciidoc
+
+
+ ${basedir}/target/generated-guides/ui-customization
+
+ ${project.build.directory}/generated-docs/ui-customization
+ true
+
+
@@ -246,4 +263,4 @@
-
+
\ No newline at end of file
diff --git a/docs/guides/ui-customization/avatars.adoc b/docs/guides/ui-customization/avatars.adoc
new file mode 100644
index 00000000000..1709323c5a2
--- /dev/null
+++ b/docs/guides/ui-customization/avatars.adoc
@@ -0,0 +1,29 @@
+<#import "/templates/guide.adoc" as tmpl>
+<#import "/templates/links.adoc" as links>
+
+<@tmpl.guide
+title="Using Avatars"
+priority=50
+summary="Use avatars in the Admin console and Account console.">
+
+Both the admin and account consoles allow use of an avatar to personalize the user experience. {project_name} supports avatars using the oidc standard `picture` claim.
+
+This `picture` claim should have a URI as its value. The URI should point to the avatar meant to be displayed in the masthead section of the admin console or account console.
+
+== Setting a picture attribute from the admin console
+The simplest way to allow users to specify the avatar URI is to add a `picture` attribute in User profile. Just go to the admin console and navigate to the `Realm Settings -> User profile` tab.
+
+Here is an example setup of the `picture` attribute:
+
+image::ui-customization/picture-attribute-general-settings.png[caption="",title="User profile picture attribute setup in admin console"]
+
+== Avatar success
+Here is the result in account console once the URI is saved for the picture attribute:
+
+image::ui-customization/account-console-with-avatar.png[caption="",title="Avatar shown in account console"]
+
+== Important warning
+CAUTION: Allowing users to specify their own URI could lead to security concerns. An avatar can contain malware. So ensure that images come from a trusted source. One practical approach is to make sure that the `picture` has a regular expression validator to restrict the URI.
+
+image::ui-customization/avatar-validation.png[caption="",title="RegExp validator for User profile picture attribute"]
+@tmpl.guide>
\ No newline at end of file
diff --git a/docs/guides/ui-customization/creating-your-own-console.adoc b/docs/guides/ui-customization/creating-your-own-console.adoc
new file mode 100644
index 00000000000..336595cbcdb
--- /dev/null
+++ b/docs/guides/ui-customization/creating-your-own-console.adoc
@@ -0,0 +1,200 @@
+<#import "/templates/guide.adoc" as tmpl>
+<#import "/templates/links.adoc" as links>
+
+<@tmpl.guide
+title="Creating your own Console"
+priority=70
+summary="Learn to create your own version of Admin Console or Account Console.">
+
+The Admin Console and Account Console are based on React.
+To create your own version of these consoles, you can use these React based npm packages:
+
+* `@keycloak/keycloak-admin-ui`: This is the base theme for the Admin Console.
+* `@keycloak/keycloak-account-ui`: This is the base theme for the Account Console.
+
+Both packages are available in the public npm repository.
+
+The goal of these packages is to allow the developer to create new React-based consoles that will continue to function properly with new versions of {project_name}.
+
+Additionally, {project_name} provides a tool called `create-keycloak-theme` that helps you get started. Full documentation for this tool can be found https://github.com/keycloak/keycloak/tree/main/js/apps/create-keycloak-theme[here].
+
+== Getting started
+
+First, we install the `create-keycloak-theme` tool. Note that we are using `pnpm`, but plain `npm` should work as well.
+[source,bash]
+----
+pnpm install -g create-keycloak-theme
+----
+
+Next, we use the tool to create a full build environment for our new console. In this example, we create a new Account Console, but everything that follows applies to creation of an Admin Console. You would just change the `-t` parameter in the following command.
+[source,bash]
+----
+pnpm create keycloak-theme my-theme -t account
+----
+
+Next, we install npm libraries.
+[source,bash]
+----
+cd my-theme
+pnpm install
+----
+
+Now, we start up the development environment, which uses https://vite.dev/guide/[Vite]. This will allow code changes to immediately show up in your browser.
+[source,bash]
+----
+pnpm run dev
+----
+
+Then we start a keycloak server. It will be automatically downloaded, started, and linked to the development environment.
+[source,bash]
+----
+pnpm run start-keycloak
+----
+
+Now everything is set up and we are ready to start hacking. To see a customized version of the Account Console, point your browser to http://localhost:8080/realms/master/account.
+
+The user name and password are both `admin`. Once logged in, you will see the new Account Console rendered:
+
+image::ui-customization/custom-account-console.png[title="Custom Account Console"]
+
+[NOTE]
+If you need to use the Admin Console, go to http://localhost:8080
+
+== Adding a new page
+
+The first thing we want to do is add a new page to our custom Account Console. You will see that there is already a template for this, `/src/MyPage.tsx`.
+
+image::ui-customization/myPage.png[title="MyPage.tsx"]
+
+There are a few parts of the code to take note of. First, there is the import statement starting with line 1:
+[source,javascript]
+----
+import {
+ AccountEnvironment,
+ Page,
+ UserRepresentation,
+ getPersonalInfo,
+ savePersonalInfo,
+ useAlerts,
+ useEnvironment,
+ usePromise,
+} from "@keycloak/keycloak-account-ui";
+----
+
+These imports of components and functions are from the aformentioned library `@keycloak/keycloak-account-ui`. This library will stay up to date with new versions of {project_name}. Therefore, you can rely on this library across releases and not worry that your version of Account Console will break.
+
+For a full list of the exports from this library, see the https://github.com/keycloak/keycloak/blob/main/js/apps/account-ui/src/index.ts[source code.]
+
+Incidentally, if you are instead creating an Admin Console, see this https://github.com/keycloak/keycloak/blob/main/js/apps/admin-ui/src/index.ts[source code.]
+
+You may notice that there is already a link in the lefthand navigation for `MyPage.tsx`, which shows up as `myPage`. If you click on that link, you will see `MyPage.tsx` in action. This was accomplished in the `routes.tsx` file.
+
+For `myPage`, the important parts in `routes.tsx` are as follows:
+[source,javascript]
+----
+import { MyPage } from "./MyPage";
+----
+[source,javascript,subs="specialcharacters,quotes"]
+----
+export const **MyPageRoute**: RouteObject = {
+ path: "myPage",
+ element: ,
+};
+
+export const RootRoute: RouteObject = {
+ path: decodeURIComponent(new URL(environment.baseUrl).pathname),
+ element: ,
+ errorElement: <>Error>,
+ children: [
+ PersonalInfoRoute,
+ DeviceActivityRoute,
+ LinkedAccountsRoute,
+ SigningInRoute,
+ ApplicationsRoute,
+ GroupsRoute,
+ ResourcesRoute,
+ **MyPageRoute**,
+ ],
+};
+----
+
+The last thing to notice is that in your development environment, the navigation link to `MyPage.tsx` is rendered as "myPage". We would rather see this rendered as "My Page". The good news is that when you do the production build of your custom Account Console, it will be properly rendered. `myPage` is a localization key that will be resolved to the proper language at runtime. To see the keys and values for English, look in `\maven-resources\theme\my-account\account\messages\messages_en.properties`.
+
+== Modifying an existing page
+
+You may wish to modify one of the Account Console pages that already exists in {project_name}. One approach is to simply re-create the entire page yourself using the method in the previous section.
+
+But you may instead wish to start with the source code from the Keycloak project. If that is your choice, you can find the source code for all the pages in the Keycloak GitHub project https://github.com/keycloak/keycloak/tree/main/js/apps/account-ui/src[here].
+
+As an example, we will use the Device Activity page (`DeviceActivity.tsx`). Let's assume that we want to remove the details from each device. We start with a screen that looks like this:
+
+image::ui-customization/device-activity-before.png[title="We want to remove the indicated details from DeviceActivity.tsx"]
+
+We will need to modify the original source code and replace the page found in `@keycloak/keycloak-account-ui`.
+
+First, download DeviceActivity.tsx from https://github.com/keycloak/keycloak/blob/main/js/apps/account-ui/src/account-security/DeviceActivity.tsx[GitHub].
+
+Then remove the details block from template and remove any unused imports.
+
+In addition to this, there are some other changes you will need to make in order to allow your new page to work properly with your custom Account Console.
+
+These imports will now come from the library `@keycloak/keycloak-account-ui`:
+
+[source,javascript,subs="specialcharacters,quotes"]
+----
+import { deleteSession, getDevices } from "../api/methods";
+import {
+ ClientRepresentation,
+ DeviceRepresentation,
+ SessionRepresentation,
+} from "../api/representations";*/
+import { Page } from "../components/page/Page";
+----
+
+Here is the new import statement:
+[source,javascript]
+----
+import {
+ AccountEnvironment,
+ Page,
+ usePromise,
+ DeviceRepresentation,
+ SessionRepresentation,
+ deleteSession,
+ getDevices,
+ useAlerts,
+ useEnvironment, // <---- moved from ui-shared
+} from "@keycloak/keycloak-account-ui";
+----
+
+Note that the `useEnvironment' function is also added to this import.
+
+The last problem to take care of is the PatternFly icons. These icons are not referenced anywhere else in your project. So you will need to add this as a dependency.
+
+[source,bash]
+----
+pnpm install @patternfly/react-icons
+----
+
+Finally, we need to change `routes.tsx` in order to replace the old Device Activity page with our new version. This is just a matter of removing the `DeviceActivity` import from `@keycloak/keycloak-account-ui` and adding an import that points to our new source file:
+
+[source,javascript]
+----
+import { DeviceActivity } from "./DeviceActivity";
+----
+
+Once all this is complete, your new Device Activity page will look like this:
+
+image::ui-customization/device-activity-after.png[title="DeviceActivity.tsx with details removed"]
+
+== Deploying your custom console
+
+The last step is to build and deploy your custom console. For this, you may need to https://maven.apache.org/[install Maven]. With Maven installed, run:
+
+[source,bash]
+----
+mvn package
+----
+
+If the build is successful, you will see a jar created in the `/target` directory. This jar can now be deployed to production by copying it to the `/providers` directory of the {project_name} server.
+@tmpl.guide>
\ No newline at end of file
diff --git a/docs/guides/ui-customization/index.adoc b/docs/guides/ui-customization/index.adoc
new file mode 100644
index 00000000000..57954bd1340
--- /dev/null
+++ b/docs/guides/ui-customization/index.adoc
@@ -0,0 +1,12 @@
+= Keycloak UI customization guide
+
+include::../attributes.adoc[]
+
+<#list ctx.guides as guide>
+:links_ui_customization_${guide.id}_name: ${guide.title}
+:links_ui_customization_${guide.id}_url: #${guide.id}
+#list>
+
+<#list ctx.guides as guide>
+include::${guide.template}[leveloffset=+1]
+#list>
diff --git a/docs/guides/ui-customization/introduction.adoc b/docs/guides/ui-customization/introduction.adoc
new file mode 100644
index 00000000000..837e18d2952
--- /dev/null
+++ b/docs/guides/ui-customization/introduction.adoc
@@ -0,0 +1,14 @@
+<#import "/templates/guide.adoc" as tmpl>
+<#import "/templates/links.adoc" as links>
+
+<@tmpl.guide
+title="Introduction"
+priority=10
+summary="Learn how to customize the user interfaces.">
+
+{project_name} includes user interfaces (UIs) for the login page, Admin Console, and Account Console. It also has a "welcome" screen used for the first administrator of the Admin Console.
+
+You can customize, extend, and modify these UIs to accommodate many use cases on your production systems. At a minimum, you will need to change the logos and colors to match your corporate identity. Also, you may modify the UIs to implement new functionality.
+
+This guide provides all the information needed to customize the {project_name} UIs for your needs.
+@tmpl.guide>
\ No newline at end of file
diff --git a/docs/guides/ui-customization/localization.adoc b/docs/guides/ui-customization/localization.adoc
new file mode 100644
index 00000000000..a31c0052cf9
--- /dev/null
+++ b/docs/guides/ui-customization/localization.adoc
@@ -0,0 +1,100 @@
+<#import "/templates/guide.adoc" as tmpl>
+<#import "/templates/links.adoc" as links>
+
+<@tmpl.guide
+title="Localization"
+priority=40
+summary="Learn how to localize strings in the UIs.">
+
+{project_name} supports localized text throughout all user interfaces.
+
+.Prerequisites
+
+* You enable internationalization for a realm in the `Realm settings` section of the Admin Console. See {adminguide_link}#enabling-internationalization[Enabling internationalization].
+
+== Localizing messages in a theme
+
+Text in the templates is loaded from message bundles. When a theme extends another theme, the child theme inherits all messages from the parent's message bundle. You can
+override individual messages by adding `/messages/messages_en.properties` to your theme.
+
+For example, to replace `Username` on the login form with `Your Username` for the `mytheme`, create the file
+`themes/mytheme/login/messages/messages_en.properties` with the following content:
+
+[source]
+----
+usernameOrEmail=Your Username
+----
+
+Within a message, values like `{0}` and `{1}` are replaced with arguments when the message is used. For example {0} in `Log in to {0}` is replaced with the name
+of the realm.
+
+Texts of these message bundles can be overwritten by realm-specific values, which are manageable by the UI and API.
+
+== Adding a language to a theme
+
+.Procedure
+
+. Create the file `/messages/messages_.properties` in the directory of your theme.
+
+. Add this file to the `locales` property in `/theme.properties`.
+For a language to be available to users in a realm, the login, account, and email theme types must support the language, so you need to add your language for those theme types.
++
+For example, to add Norwegian translations to the `mytheme` theme, create the file `themes/mytheme/login/messages/messages_no.properties` with the
+following content:
++
+[source]
+----
+usernameOrEmail=Brukernavn
+password=Passord
+----
++
+If you omit a translation for messages, those messages appear in English.
+
+. Edit `themes/mytheme/login/theme.properties` and add:
++
+[source]
+----
+locales=en,no
+----
+
+. Make the same changes to the `account` and `email` theme types. To make these changes, create `themes/mytheme/account/messages/messages_no.properties` and
+`themes/mytheme/email/messages/messages_no.properties`. If you leave these files empty, English messages appear.
+
+. Copy `themes/mytheme/login/theme.properties` to `themes/mytheme/account/theme.properties` and `themes/mytheme/email/theme.properties`.
+
+. Add a translation for the language selector by adding a message to the English translation. Add the following to
+`themes/mytheme/account/messages/messages_en.properties` and `themes/mytheme/login/messages/messages_en.properties`:
++
+[source]
+----
+locale_no=Norsk
+----
+
+By default, message properties files should be encoded using UTF-8.
+{project_name} falls back to ISO-8859-1 handling if it cannot read the contents as UTF-8.
+Unicode characters can be escaped as described in Java's documentation for https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/PropertyResourceBundle.html[PropertyResourceBundle].
+Previous versions of {project_name} had support for specifying the encoding in the first line with a comment such as `# encoding: UTF-8`, which is no longer supported.
+
+[role="_additional-resources"]
+.Additional resources
+* For details on how the current locale is selected, see {developerguide_link}#_locale_selector[Locale Selector].
+
+== Overriding localized text for an entire realm
+
+You also have the option to declare translations that take effect for an entire realm. You specify key/value pairs in the realm settings. Any key specified in this way overrides the key/value pairs deployed with a theme.
+
+CAUTION: In most cases, using realm overrides is not the recommended way to achieve localization in {project_name}. Consider carefully if you want every theme in your realm to use a key/value pair declared as a realm override.
+
+.Procedure to add a realm override
+
+. Log into the Admin Console.
+. Select your realm.
+. Click *Realm Settings* from the menu.
+. Click on the *Localization* tab.
+. Click on the *Realm overrides* subtab.
+. Select a language from the option list.
+. Click *Add translation*.
+. Create a key/value pair from the modal dialog.
+
+Notice another subtab called *Effective message bundles*. This subtab provides a tool to query key/value pairs for a combination of theme, language, and theme type. You can use this tool to test and make sure your realm overrides took effect.
+@tmpl.guide>
\ No newline at end of file
diff --git a/docs/guides/ui-customization/quick-theme.adoc b/docs/guides/ui-customization/quick-theme.adoc
new file mode 100644
index 00000000000..ea00fc66a96
--- /dev/null
+++ b/docs/guides/ui-customization/quick-theme.adoc
@@ -0,0 +1,63 @@
+<#import "/templates/guide.adoc" as tmpl>
+<#import "/templates/links.adoc" as links>
+
+<@tmpl.guide
+title="Customizing with Quick Theme"
+priority=30
+preview="true"
+summary="Learn how to customize the consoles and login screens with the Quick Theme utility.">
+
+"Quick Theme" is an experimental feature which allows you to quickly and easily create themes with new logos and colors. Often, this is all you need to facilitate branding and skinning for the Account Console, Admin Console, and login page.
+
+== Enabling Quick Theme
+
+Because the "Quick Theme" feature is experimental, you will need to enable this feature using a feature flag as you start the server.
+
+For example:
+[source,bash]
+----
+bin/kc.[sh|bat] start --features=quick-theme
+----
+
+== Setting logos and colors
+The "Quick Theme" tool is shown below. The theme you create will extend the default {project_name} theme. Therefore, when you want to create a new theme with the tool you will start out with the default colors and images.
+
+image::ui-customization/quick-theme-overview.png[title="Quick Theme"]
+
+As shown below, when you change a color or image, you get a preview of how your colors and images will look together for various elements of your theme. The color options correspond to https://www.patternfly.org/developer-resources/global-css-variables/[PatternFly global CSS variables], which are used by {project_name} to create themes.
+
+image::ui-customization/simple-quick-theme-changes.png[title="Preview after changes"]
+
+[TIP]
+====
+The "Quick Theme" tool uses the default color chooser from your browser. Some color choosers, such as in Chrome, have a handy tool to find a color from something on your screen. Notice the "dropper" icon in the lefthand side of the dialog.
+
+image::ui-customization/color-chooser.png[alt="Color chooser with dropper", title="Color chooser with the dropper tool"]
+
+This "dropper" tool can be used to select your background color to match a color in your logo.
+
+.Find a color with the dropper tool
+image::ui-customization/easy-theme-find-color.png[alt="Find a color with the dropper tool", title="Find a color with the dropper tool"]
+====
+
+When your new theme is complete, click *Download theme JAR* to download a theme JAR that is ready for deployment.
+
+=== Deploying your theme
+Once you have downloaded your theme's archive jar, it's time to deploy and try it out. To deploy the archive to {project_name}, add it to the `providers/` directory of {project_name} and restart the server if it is already running.
+
+CAUTION: For security reasons, never deploy a theme unless you are confident of its origin. An image can be a possible attack vector. This issue is the reason that {project_name} does not allow automatic deployment of a theme through the Admin Console. Only those administrators with file access to your production server should deploy a theme in production.
+
+Another deployment option is to "unjar" the archive into the `themes/` directory. With this option, you explore the theme and make manual changes.
+
+Many compression utilities or "zip tools" support `jar` files and you can use these to "unjar" the file. If no such utility is available, you can use the `jar` utility that comes with the java JDK.
+
+[source,bash]
+----
+jar xf quick-theme.jar
+----
+
+=== Trying out your new theme
+Your theme includes the images and colors you provided. They appear throughout the Account Console, Admin Console, and login page.
+
+Once your "Quick Theme" archive jar is deployed, you can fully test it using the procedures shown in the <>. Essentially, you just need to choose your new theme on the Realm settings --> Themes tab.
+@tmpl.guide>
diff --git a/docs/guides/ui-customization/themes-react.adoc b/docs/guides/ui-customization/themes-react.adoc
new file mode 100644
index 00000000000..c403e42dea5
--- /dev/null
+++ b/docs/guides/ui-customization/themes-react.adoc
@@ -0,0 +1,69 @@
+<#import "/templates/guide.adoc" as tmpl>
+<#import "/templates/links.adoc" as links>
+
+<@tmpl.guide
+title="Using the npm UI packages"
+priority=80
+summary="Learn how to use UI modules in your own application.">
+
+A final approach to customization is to just take pieces of the Admin Console or Account Console and use it in your own React application.
+
+To fully customize these consoles, you can use the aformentioned React based npm packages.
+Two packages exist:
+
+* `@keycloak/keycloak-admin-ui`: This is the base theme for the Admin Console.
+* `@keycloak/keycloak-account-ui`: This is the base theme for the Account Console.
+Both packages are available in the public npm repository.
+
+== Installing the packages
+
+To install the packages, run the following command:
+
+[source,bash]
+----
+pnpm install @keycloak/keycloak-account-ui
+----
+
+== Using the packages
+
+To use these pages, you add KeycloakProvider in your component hierarchy to choose the client, realm, and URL that you need.
+
+[source,javascript]
+----
+import { KeycloakProvider } from "@keycloak/keycloak-ui-shared";
+
+//...
+
+
+ {/* rest of you application */}
+
+----
+
+== Translating the pages
+
+The pages are translated using the `i18next` library.
+You can set it up as described on the https://react.i18next.com/[react-i18next Website].
+If you want to use the translations that are provided, add i18next-http-backend to your project and add the following:
+
+[source,javascript]
+----
+backend: {
+ loadPath: `http://localhost:8080/resources/master/account/{lng}}`,
+ parse: (data: string) => {
+ const messages = JSON.parse(data);
+
+ const result: Record = {};
+ messages.forEach((v) => (result[v.key] = v.value)); //need to convert to record
+ return result;
+ },
+},
+----
+
+== Using the pages
+
+To see how to further integrate the pages, we recommend that you take a look at the output of the tool in the <> chapter.
+@tmpl.guide>
\ No newline at end of file
diff --git a/docs/guides/ui-customization/themes.adoc b/docs/guides/ui-customization/themes.adoc
new file mode 100644
index 00000000000..5231885847d
--- /dev/null
+++ b/docs/guides/ui-customization/themes.adoc
@@ -0,0 +1,411 @@
+<#import "/templates/guide.adoc" as tmpl>
+<#import "/templates/links.adoc" as links>
+
+<@tmpl.guide
+title="Working with themes"
+priority=20
+summary="Understand how to create and configure themes.">
+
+{project_name} provides theme support for web pages and emails. This allows customizing the look and feel of end-user facing pages so they can be
+integrated with your applications.
+
+image::ui-customization/login-sunrise.png[caption="",title="Login page with sunrise example theme"]
+
+== Theme types
+
+A theme can provide one or more types to customize different aspects of {project_name}. The types available are:
+
+* Account - Account Console
+* Admin - Admin Console
+* Email - Emails
+* Login - Login forms
+* Welcome - Welcome page
+
+== Configuring a theme
+
+All theme types, except welcome, are configured through the Admin Console.
+
+.Procedure
+
+. Log into the Admin Console.
+. Select your realm from the drop-down box in the top left corner.
+. Click *Realm Settings* from the menu.
+. Click the *Themes* tab.
++
+NOTE: To set the theme for the `master` Admin Console you need to set the Admin Console theme for the `master` realm.
++
+. To see the changes to the Admin Console refresh the page.
+
+. Change the welcome theme by using the `spi-theme-welcome-theme` option.
+
+. For example:
++
+[source,bash]
+----
+bin/kc.[sh|bat] start --spi-theme-welcome-theme=custom-theme
+----
+
+[[_default-themes]]
+== Default themes
+
+{project_name} comes bundled with default themes in the JAR file `keycloak-themes-{project_versionMvn}.jar` inside the server distribution.
+The server's root `themes` directory does not contain any themes by default, but it contains a README file with some additional details about the default themes.
+To simplify upgrading, do not edit the bundled themes directly. Instead create your own theme that extends one of the bundled themes.
+
+[[_creating-a-theme]]
+== Creating a theme
+
+A theme consists of:
+
+* HTML templates (https://freemarker.apache.org/[Freemarker Templates])
+* Images
+* Message bundles
+* Stylesheets
+* Scripts
+* Theme properties
+
+Unless you plan to replace every single page you should extend another theme. Most likely you will want to extend some existing theme. Alternatively, if you intend to provide your own implementation of the admin or account console,
+consider extending the `base` theme. The `base` theme consists of a message bundle and therefore such implementation needs to start from scratch, including implementation of the main `index.ftl` Freemarker template, but it can leverage existing translations from the message bundle.
+
+When extending a theme you can override individual resources (templates, stylesheets, etc.). If you decide to override HTML templates bear in mind that you may
+need to update your custom template when upgrading to a new release.
+
+While creating a theme it's a good idea to disable caching as this makes it possible to edit theme resources directly from the `themes` directory without
+restarting {project_name}.
+
+.Procedure
+
+. Run Keycloak with the following options:
++
+[source,bash]
+----
+bin/kc.[sh|bat] start --spi-theme-static-max-age=-1 --spi-theme-cache-themes=false --spi-theme-cache-templates=false
+----
+
+. Create a directory in the `themes` directory.
++
+The name of the directory becomes the name of the theme. For example to
+create a theme called `mytheme` create the directory `themes/mytheme`.
+
+. Inside the theme directory, create a directory for each of the types your theme is going to provide.
++
+For example, to add the login type to the `mytheme` theme, create the directory `themes/mytheme/login`.
+
+. For each type create a file `theme.properties` which allows setting some configuration for the theme.
++
+For example, to configure the theme `themes/mytheme/login` to extend the `base` theme and import some common resources, create the file `themes/mytheme/login/theme.properties` with following contents:
++
+[source]
+----
+parent=base
+import=common/keycloak
+----
++
+You have now created a theme with support for the login type.
+
+. Log into the Admin Console to check out your new theme
+. Select your realm
+. Click *Realm Settings* from the menu.
+. Click on the *Themes* tab.
+. For *Login Theme* select *mytheme* and click *Save*.
+. Open the login page for the realm.
++
+You can do this either by logging in through your application or by opening the Account Console (`/realms/{realm-name}/account`).
+
+. To see the effect of changing the parent theme, set `parent=keycloak` in `theme.properties` and refresh the login page.
+
+[NOTE]
+====
+Be sure to re-enable caching in production as it will significantly impact performance.
+====
+[NOTE]
+====
+If you want to manually delete the content of the themes cache, you can do so by deleting the `data/tmp/kc-gzip-cache` directory of the server distribution.
+It can be useful for instance if you redeployed custom providers or custom themes without disabling themes caching in the previous server executions.
+====
+
+=== Theme properties
+
+Theme properties are set in the file `/theme.properties` in the theme directory.
+
+* parent - Parent theme to extend
+* import - Import resources from another theme
+* common - Override the common resource path. The default value is `common/keycloak` when not specified. This value would be used as value of suffix of ${r"`${url.resourcesCommonPath}`"}, which is used typically in freemarker templates (prefix of ${r"`${url.resoucesCommonPath}`"} value is theme root uri).
+* styles - Space-separated list of styles to include
+* locales - Comma-separated list of supported locales
+
+There are a list of properties that can be used to change the css class used for certain element types. For a list of these properties look at the theme.properties
+file in the corresponding type of the keycloak theme (`themes/keycloak//theme.properties`).
+
+You can also add your own custom properties and use them from custom templates.
+
+When doing so, you can substitute system properties or environment variables by using these formats:
+
+* ${r"`${some.system.property}`"} - for system properties
+* ${r"`${env.ENV_VAR}`"} - for environment variables.
+
+A default value can also be provided in case the system property or the environment variable is not found with ${r"`${foo\:defaultValue}`"}.
+
+NOTE: If no default value is provided and there's no corresponding system property or environment variable, then nothing is replaced and you end up with the format in your template.
+
+Here's an example of what is possible:
+
+[source,properties]
+----
+javaVersion=${r"${java.version}"}
+
+unixHome=${r"${env.HOME:Unix home not found}"}
+windowsHome=${r"${env.HOMEPATH:Windows home not found}"}
+----
+
+[[_theme_stylesheet]]
+=== Add a stylesheet to a theme
+
+You can add one or more stylesheets to a theme.
+
+.Procedure
+
+. Create a file in the `/resources/css` directory of your theme.
+
+. Add this file to the `styles` property in `theme.properties`.
++
+For example, to add `styles.css` to the `mytheme`, create `themes/mytheme/login/resources/css/styles.css` with the following content:
++
+[source,css]
+----
+.login-pf body {
+ background: DimGrey none;
+}
+----
+
+. Edit `themes/mytheme/login/theme.properties` and add:
++
+[source]
+----
+styles=css/styles.css
+----
+
+. To see the changes, open the login page for your realm.
++
+You will notice that the only styles being applied are those from your custom stylesheet.
+
+. To include the styles from the parent theme, load the styles from that theme. Edit `themes/mytheme/login/theme.properties` and change `styles` to:
++
+[source]
+----
+styles=css/login.css css/styles.css
+----
++
+NOTE: To override styles from the parent stylesheets, ensure that your stylesheet is listed last.
+
+=== Adding a script to a theme
+
+You can add one or more scripts to a theme.
+
+.Procedure
+
+. Create a file in the `/resources/js` directory of your theme.
+
+. Add the file to the `scripts` property in `theme.properties`.
++
+For example, to add `script.js` to the `mytheme`, create `themes/mytheme/login/resources/js/script.js` with the following content:
++
+[source,javascript]
+----
+alert('Hello');
+----
++
+Then edit `themes/mytheme/login/theme.properties` and add:
++
+[source]
+----
+scripts=js/script.js
+----
+
+=== Adding an image to a theme
+
+To make images available to the theme add them to the `/resources/img` directory of your theme. These can be used from within stylesheets or
+directly in HTML templates.
+
+For example to add an image to the `mytheme` copy an image to `themes/mytheme/login/resources/img/image.jpg`.
+
+You can then use this image from within a custom stylesheet with:
+
+[source,css]
+----
+body {
+ background-image: url('../img/image.jpg');
+ background-size: cover;
+}
+----
+
+Or to use directly in HTML templates add the following to a custom HTML template:
+
+[source,html]
+----
+
+----
+
+[[_theme_custom_footer]]
+=== Adding a custom footer to a login theme
+
+In order to use a custom footer, create a `footer.ftl` file in your custom login theme with the desired content.
+
+An example for a custom `footer.ftl` may look like this:
+```
+<#macro content>
+<#-- footer at the end of the login box -->
+
+
+
+#macro>
+```
+
+=== Adding an image to an email theme
+
+To make images available to the theme add them to the `/email/resources/img` directory of your theme. These can be used from within directly in HTML templates.
+
+For example to add an image to the `mytheme` copy an image to `themes/mytheme/email/resources/img/logo.jpg`.
+
+To use directly in HTML templates add the following to a custom HTML template:
+
+[source,html]
+----
+
+----
+
+[[custom-identity-providers-icons]]
+=== Adding custom Identity Providers icons
+
+{project_name} supports adding icons for custom Identity providers, which are displayed on the login screen.
+
+.Procedure
+
+. Define icon classes in your login `theme.properties` file (for example, `themes/mytheme/login/theme.properties`) with key pattern `kcLogoIdP-`.
+
+. For an Identity Provider with an alias `myProvider`, you may add a line to `theme.properties` file of your custom theme. For example:
++
+[source]
+----
+kcLogoIdP-myProvider = fa fa-lock
+----
+
+All icons are available on the official website of PatternFly4.
+Icons for social providers are already defined in `base` login theme properties (`themes/keycloak/login/theme.properties`), where you can inspire yourself.
+
+=== Creating a custom HTML template
+
+{project_name} uses https://freemarker.apache.org/[Apache Freemarker] templates to generate HTML and render pages.
+
+Although it is possible to create custom templates to change completely how pages are rendered, the recommendation is to leverage the built-in
+templates as much as possible. The reasons are:
+
+* During upgrades, you might be forced to update your custom templates to get the latest updates from newer versions
+* link:#_theme_stylesheet[Configuring CSS styles] to your themes allows you to adapt the UI to match your UI design standards and guidelines.
+* link:{adminguide_link}#user-profile[User Profile] allows you to support custom user attributes and configure how they are rendered.
+
+In most cases, you won't need to change templates to adapt {project_name} to your needs, but you can override individual
+templates in your own theme by creating `/.ftl`.
+Admin and account console use a single template `index.ftl` for rendering the application.
+
+For a list of templates in other theme types look at the `theme/base/` directory in the JAR file at `$KEYCLOAK_HOME/lib/lib/main/org.keycloak.keycloak-themes-.jar`.
+
+.Procedure
+
+. Copy the template from the base theme to your own theme.
+
+. Apply the modifications you need.
++
+For example, to create a custom login form for the `mytheme` theme, copy `themes/base/login/login.ftl` to `themes/mytheme/login` and open it in an editor.
++
+${r"After the first line (<#import ...>), add `HELLO WORLD!
` as shown here:"}
++
+[source,html]
+----
+${r"<#import"} "template.ftl" as layout>
+HELLO WORLD!
+...
+----
+
+. Back up the modified template. When upgrading to a new version of {project_name} you may need to update your custom templates to apply changes to the original template if applicable.
+
+[role="_additional-resources"]
+.Additional resources
+* See the https://freemarker.apache.org/docs/index.html[FreeMarker Manual] for details on how to edit templates.
+
+=== Emails
+
+To edit the subject and contents for emails, for example password recovery email, add a message bundle to the `email` type of your theme. There are three messages for each email. One for the subject, one for the plain text body and one for the html body.
+
+To see all emails available take a look at `themes/base/email/messages/messages_en.properties`.
+
+For example to change the password recovery email for the `mytheme` theme create `themes/mytheme/email/messages/messages_en.properties` with the following
+content:
+[source]
+----
+passwordResetSubject=My password recovery
+passwordResetBody=Reset password link: {0}
+passwordResetBodyHtml=Reset password
+----
+
+== Deploying themes
+
+Themes can be deployed to {project_name} by copying the theme directory to `themes` or it can be deployed as an archive. During development you can copy the
+theme to the `themes` directory, but in production you may want to consider using an `archive`. An `archive` makes it simpler to have a versioned copy of
+the theme, especially when you have multiple instances of {project_name} for example with clustering.
+
+.Procedure
+
+. To deploy a theme as an archive, create a JAR archive with the theme resources.
+. Add a file `META-INF/keycloak-themes.json` to the
+archive that lists the available themes in the archive as well as what types each theme provides.
++
+For example for the `mytheme` theme create `mytheme.jar` with the contents:
++
+* META-INF/keycloak-themes.json
+* theme/mytheme/login/theme.properties
+* theme/mytheme/login/login.ftl
+* theme/mytheme/login/resources/css/styles.css
+* theme/mytheme/login/resources/img/image.png
+* theme/mytheme/login/messages/messages_en.properties
+* theme/mytheme/email/messages/messages_en.properties
++
+The contents of `META-INF/keycloak-themes.json` in this case would be:
++
+[source,json]
+----
+{
+ "themes": [{
+ "name" : "mytheme",
+ "types": [ "login", "email" ]
+ }]
+}
+----
++
+A single archive can contain multiple themes and each theme can support one or more types.
+
+To deploy the archive to {project_name}, add it to the `providers/` directory of
+{project_name} and restart the server if it is already running.
+
+== Dark Mode
+Dark mode is a feature that changes the color scheme to a dark background with lighter text. For example, themes based on PatternFly, such as Keycloak's admin console and account console, support dark mode. But for some themes, dark mode doesn't work well for various reasons. So Keycloak allows you to disable dark mode from the admin console.
+
+.Procedure to disable dark mode
+
+. Log into the Admin Console.
+. Select your realm.
+. Click *Realm Settings* from the menu.
+. Click on the *Themes* tab.
+. Unselect *Dark mode* and click *Save*.
+
+If enabled, the dark variant of the theme will be applied based on user preference through an operating system setting (e.g. light or dark mode) or a user agent setting. If disabled, only the light variant will be used. This setting only applies to themes that support dark and light variants. On themes that do not support this feature it will have no effect.
+
+[role="_additional-resources"]
+== Additional resources for Themes
+* For more inspiration, see <<_default-themes,Default Themes>> bundled inside {project_name}.
+* {quickstartRepo_link}[{quickstartRepo_name}] - Directory `extension` of the quickstarts repository contains some theme examples, which can be also used as an inspiration.
+@tmpl.guide>
\ No newline at end of file
diff --git a/docs/guides/ui-customization/welcome-theme.adoc b/docs/guides/ui-customization/welcome-theme.adoc
new file mode 100644
index 00000000000..40cd61b4713
--- /dev/null
+++ b/docs/guides/ui-customization/welcome-theme.adoc
@@ -0,0 +1,20 @@
+<#import "/templates/guide.adoc" as tmpl>
+<#import "/templates/links.adoc" as links>
+
+<@tmpl.guide
+title="Customizing the Welcome Theme"
+priority=60
+summary="Learn how to customize the welcome theme.">
+
+The welcome theme is the web page that is served when you request the default page from the {project_name} server. For instance, if your server is deployed on your local machine at port 8080, http://localhost:8080 serves the welcome theme.
+
+By default, the welcome theme is only used to create the initial temporary admin user. Once that user is created, whenever users navigate to the welcome theme, they are redirected to the Admin Console. However, this behavior can be changed and the welcome theme can be completely customized or replaced.
+
+Since the welcome theme is not associated with a realm, it cannot be selected in the admin console like other themes.
+
+To change the welcome theme, create and deploy a new welcome theme as described in <<_creating-a-theme,Creating a theme>>. Then, start the {project_name} server using the `spi-theme-welcome-theme` option.
+[source,bash]
+----
+bin/kc.[sh|bat] start --spi-theme-welcome-theme=custom-theme
+----
+@tmpl.guide>
\ No newline at end of file