Red Hat Developer Hub 1.8

Customizing Red Hat Developer Hub

Customizing Red Hat Developer Hub appearance and features, such as templates, Learning Paths, Tech Radar, Home page, and quick access cards

Red Hat Customer Content Services

Abstract

Authorized users can customize Red Hat Developer Hub (RHDH) appearance and features, such as templates, Learning Paths, Tech Radar, Home page, and quick access cards.

Authorized users can customize Red Hat Developer Hub (RHDH) appearance and features, such as templates, Learning Paths, Tech Radar, Home page, and quick access cards.

1. Customizing your Red Hat Developer Hub title

You can change the default Red Hat Developer Hub display name.

Procedure

  • In your custom app-config.yaml file, enter your Developer Hub instance display name, such as <Red Hat Developer Hub>.

    app-config.yaml excerpt

    app:
      title: My custom Red Hat Developer Hub title

2. Customizing your Red Hat Developer Hub base URL

You can change the default Red Hat Developer Hub base URL.

Prerequisites

  • You know your desired Developer Hub external URL: https://<my_developer_hub_domain>, and have configured DNS to point to your Red Hat OpenShift Container Platform cluster.
  • Custom Developer Hub configuration.

Procedure

  • In your custom app-config.yaml file, enter your Developer Hub external URL, such as https://<my_developer_hub_domain>.

    app-config.yaml excerpt

    app:
      baseUrl: https://<my_developer_hub_domain>
    backend:
      baseUrl: https://<my_developer_hub_domain>
      cors:
        origin: https://<my_developer_hub_domain>

3. Customizing Red Hat Developer Hub backend secret

The default Red Hat Developer Hub configuration defines the Developer Hub backend secret for service to service authentication.

You can define your custom Developer Hub backend secret.

Prerequisites

Procedure

  1. To define the Developer Hub backend secret, add to your custom <my_product_secrets>.txt file the BACKEND_SECRET environment variable with a base64 encoded string. Use a unique value for each Developer Hub instance.

    $ echo > <my_product_secrets>.txt "BACKEND_SECRET=$(node -p 'require("crypto").randomBytes(24).toString("base64")')"

    <my_product_secrets>.txt example

    BACKEND_SECRET=3E2/rIPuZNFCtYHoxVP8wjriffnN1q/z

  2. Add your backend secret to your custom app-config.yaml file.

    app-config.yaml excerpt defining the backend secret

    backend:
      auth:
        externalAccess:
          - type: legacy
            options:
              subject: legacy-default-config
              secret: "${BACKEND_SECRET}"

4. About Software Templates

Software Templates in Red Hat Developer Hub provide a streamlined way to create software components and publish them to different version control repositories such as Git. Platform engineers create and maintain Software Templates in Red Hat Developer Hub.

You can configure Software Templates to create software components, and publish these components to Git repositories. Once the components are published to Git repositories, register these components in the Software Catalog.

A template is a form composed of different UI fields that is defined in a YAML file. Software Templates include actions, which are steps that are executed in sequential order and can be executed conditionally.

4.1. Creating a Software Template by using the Template Editor

Use the Red Hat Developer Hub Template Editor to create a Software Template.

Alternately, you can use the Template Editor to do any of the following actions:

  • File > Open template directory
  • File > Create template directory
  • File > Close template editor
  • Use the Custom Fields Explorer button to test custom fields in your templates.yaml file
  • View Installed Actions Documentation

Procedure

To create a Software Template by using the Template Editor templates, complete the following steps:

  1. In your Red Hat Developer Hub navigation menu, click Catalog > Self-service. Alternatively, to go to Self-service page, in your header menu, click the (+) icon.
  2. Click the More options icon and select Manage Templates.

    Template Editor
    Note
    • The following options on the Managed Templates page do not create a software component in your Red Hat Developer Hub instance:

      • Template Form Playground: Use to create and test the templates.yaml file
      • Custom Field Explorer: Use to test custom fields
  3. On the Managed Templates page, select any of the following options:

    • Load Template Directory: Use to load an existing templates.yaml file

      • In your local file manager, navigate to the folder where your templates.yaml file is stored and click Select.
    • Create New Template: Use to create a templates.yaml file

      1. In your local file manager, navigate to the folder where you want the Template Editor to create a templates.yaml file and click Select.
      2. On the Template Editor page, select the templates.yaml file.
      3. (Optional) You can preview and test your template specifications.

        1. On the Fill in some steps tab, enter text into the required fields and click Next.
        2. On the Repository Location tab, enter text into the required fields and click Review.
        3. Modify the YAML definition for the parameters of your template. For more information about these parameters, see Section 4.2, “Creating a Software Template as a YAML file”.
        4. Review the information for accuracy, then click Create.
      4. After the Software Template is created, import your Software Template in your RHDH instance.

Verification

  1. Click the Catalog tab in the navigation panel.
  2. In the Kind drop-down menu, select Template.
  3. Confirm that your template is shown in the list of existing templates.

4.2. Creating a Software Template as a YAML file

You can create a Software Template by defining a Template object as a YAML file.

The Template object describes the Software Template and its metadata. It also contains required input variables and a list of actions that are executed by the scaffolding service.

Template object example

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: template-name 1
  title: Example template 2
  description: An example template for v1beta3 scaffolder. 3
spec:
  owner: backstage/techdocs-core 4
  type: service 5
  parameters: 6
    - title: Fill in some steps
      required:
        - name
      properties:
        name:
          title: Name
          type: string
          description: Unique name of the component
        owner:
          title: Owner
          type: string
          description: Owner of the component
    - title: Choose a location
      required:
        - repoUrl
      properties:
        repoUrl:
          title: Repository Location
          type: string
  steps: 7
    - id: fetch-base
      name: Fetch Base
      action: fetch:template
      # ...
  output: 8
    links:
      - title: Repository 9
        url: ${{ steps['publish'].output.remoteUrl }}
      - title: Open in catalog 10
        icon: catalog
        entityRef: ${{ steps['register'].output.entityRef }}
# ...

1
Specify a name for the Software Template.
2
Specify a title for the Software Template. This is the title that is visible on the Software Template tile in the Self-service view.
3
Specify a description for the Software Template. This is the description that is visible on the Software Template tile in the Self-service view.
4
Specify the ownership of the Software Template. The owner field provides information about who is responsible for maintaining or overseeing the Software Template within the system or organization. In the provided example, the owner field is set to backstage/techdocs-core. This means that this Software Template belongs to the techdocs-core project in the backstage namespace.
5
Specify the component type. Any string value is accepted for this required field, but your organization should establish a proper taxonomy for these. Red Hat Developer Hub instances may read this field and behave differently depending on its value. For example, a website type component may present tooling in the Red Hat Developer Hub interface that is specific to just websites.

The following values are common for this field:

service
A backend service, typically exposing an API.
website
A website.
library
A software library, such as an npm module or a Java library.
6
Use the parameters section to specify parameters for user input that are shown in a form view when a user creates a component by using the Software Template in the Red Hat Developer Hub console. Each parameters subsection, defined by a title and properties, creates a new form page with that definition.
7
Use the steps section to specify steps that are executed in the backend. These steps must be defined by using a unique step ID, a name, and an action. You can view actions that are available on your Red Hat Developer Hub instance by visiting the URL https://<rhdh_url>/create/actions.
8
Use the output section to specify the structure of output data that is created when the template is used. The output section, particularly the links subsection, provides valuable references and URLs that users can utilize to access and interact with components that are created from the template.
9
Provides a reference or URL to the repository associated with the generated component.
10
Provides a reference or URL that allows users to open the generated component in a catalog or directory where various components are listed.

4.3. Creating a new software component using Software Templates

You can create a new software component using the standard Software Templates that the platform engineers have created. The scaffolding process runs in your Red Hat Developer Hub instance.

Procedure

  1. In your Red Hat Developer Hub navigation menu, click Catalog > Self-service.
  2. On the Self-service page, click Choose on the Templates tile to initiate the scaffolding process for a template.
  3. Follow the wizard instructions as you enter the required details. You can choose parameters from a set of pre-defined options.

    • Optional: In the Deployment Information step, you have an option to Create Workbench for OpenShift AI.

      Note

      This step is available only for a few templates.

  4. In the Review step, verify the parameters you have entered and click Create.

    Note
    • You can click Cancel to abort the software component creation during the template running step only if the current step supports the abort. The abort signal is then sent to a task and none of the following steps are executed.
    • During the creation of the software component, click Show Logs to view the log information.

Verification

  • If your software component is not created successfully, you can review the logs on the error page. To return to the Self-service page with the same template form and your previously entered values, click Start Over.
template creation not successful
  • If your Software Template is created successfully, a success page similar to the example in the following image is displayed:

    template-creation-successful

4.4. Searching and filtering Software Templates in your Red Hat Developer Hub instance

You can search and filter for the Software Template that you want to use to create a new software component.

Procedure

To search and filter for a Software Template, complete the following steps:

  1. In the Red Hat Developer Hub navigation menu, click Catalog > Self-service.
  2. Type the name of the template you are looking for in the Search box.

    • If you are looking for templates in a certain category, you can use the Categories dropdown.

4.5. Importing an existing Software Template to Red Hat Developer Hub

You can add an existing Software Template to your Red Hat Developer Hub instance by using the Catalog Processor.

Prerequisites

  • You have created a directory or repository that contains at least one template YAML file.
  • Optional: To use a template stored in a GitHub repository, you have configured Developer Hub integration with GitHub.

Procedure

  • In the app-config.yaml configuration file, modify the catalog.rules section to include a rule for Software Templates, and configure the catalog.locations section to point to the Software Template that you want to add, as shown in the following example:

    # ...
    catalog:
      rules:
        - allow: [Template] 1
      locations:
        - type: url 2
          target: https://<repository_url>/example-template.yaml 3
    # ...
    1
    To allow new Software Templates to be added to the catalog, you must add a Template rule.
    2
    If you are importing templates from a repository, such as GitHub or GitLab, use the url type.
    3
    Specify the URL for the template.

Verification

  1. Click the Catalog tab in the navigation panel.
  2. In the Kind drop-down menu, select Template.
  3. Confirm that your template is shown in the list of existing templates.

4.6. Versioning a Software Template in Red Hat Developer Hub

As a platform administrator, you can version Software Templates by using the existing custom actions catalog:scaffolded-from and catalog:template:version within the scaffolder backend module. By using these custom actions, you can track the scaffolder template version and the corresponding version of the entities created from it, which improves lifecycle management.

Prerequisites

  • You have administrator rights to Red Hat Developer Hub.

Procedure

To add versioning to a Software Template yaml file, complete the following steps:

  1. Modify the Software Template that you want to update.
  2. Complete one or both of the following tasks:

    • Include the backstage.io/template-version annotation in your template. When this annotation is present in your template, it is automatically used to annotate your catalog entity and a default version value is displayed.
    • Pass the backstage.io/template-version annotation as input to the action. This method takes precedence over the annotation in the template itself. It allows the user running the template to specify the version they wish to generate.
    # ...
    - id: version-templateRef
      name: Append the version of this template to the entityRef
      action: catalog:template:version
      input:
        annotations:
          backstage.io/template-version: ${{ parameters.version }}
    # ...

Verification

  1. Create a catalog component using the updated Software Template. This step creates a new component in Backstage and optionally, pushes files to an external repository (For example, GitHub, GitLab).
  2. Check the component in the Catalog UI.

    1. On the Catalog page, locate the newly created catalog component.
    2. Verify that the backstage.io/template-version annotation is present in the entity. You can use INSPECT ENTITY and select YAML Raw or JSON Raw view to find the annotation in the component definition.
  3. Only if you have published the catalog component: Check the component file in the repository.

    1. If VIEW SOURCE is present in your UI: Click VIEW SOURCE to open the stored component file in the repository.
    2. Locate the file manually and verify that the backstage.io/template-version annotation is present.

4.7. Enabling Software Template version update notifications in Red Hat Developer Hub

As a platform engineer, you can enable notification alerts for template version updates using the @backstage-community/plugin-catalog-backend-module-scaffolder-relation-processor module, an extension to the catalog-backend plugin. When enabled, this module automatically notifies component owners whenever the Software Template used to generate their components is updated to a new version.

This functionality uses the spec.scaffoldedFrom field in catalog entities. This field links Software Templates to the entities they have scaffolded. By tracking this relationship, the module helps teams stay informed and take advantage of the latest improvements or fixes.

The plugin-catalog-backend-module-scaffolder-relation-processor module is disabled by default.

Prerequisites

  • You have installed and configured the Backstage backend notification plugin @backstage/plugin-notifications-backend.
  • You have installed and configured the Backstage frontend plugin @backstage/plugin-notifications.

Procedure

  1. To enable the notifications, in your Red Hat Developer Hub app-config.yaml file, add the following codes:

    1. In the dynamicPlugins:frontend section:

      frontend:
        backstage.plugin-notifications:
          dynamicRoutes:
            - importName: NotificationPage
      	      menuItem:
      	        config:
      	          props:
                    titleCounterEnabled: true
      		          webNotificationsEnabled: false
      	        importName: NotificationsSidebarItem
      	        path: /notifications
    2. In a new section:

      scaffolder:
        notifications:
          templateUpdate:
            enabled: true # Set to false to disable notifications

      You can also customize the notification title and description as shown in the following code:

      scaffolder:
        notifications:
          templateUpdate:
            enabled: true
            message:
              title: 'Custom title for $ENTITY_DISPLAY_NAME'
              description: 'Custom description'

      where:

      enabled
      Set to true to enable the notification. Default value is false.
      message:title
      Enter the notification title.
      message:description
      Enter the notification description.
Note

Both message:title and message:description support the template variable $ENTITY_DISPLAY_NAME. The system automatically substitutes this variable with the title (or the name, if the title is missing) of the entity scaffolded from the updated template.

Verification

  • In your Red Hat Developer Hub instance, on the left navigation menu, you are able to see Notifications, or, if configured, the custom title.
  • When you update the version number in the Software Template, you receive a notification.

5. About Software Catalogs

The Red Hat Developer Hub Software Catalog is a centralized system that gives you visibility into all the software across your ecosystem, including services, websites, libraries, and data pipelines. You can use it to view ownership details and metadata for each component in one place.

The metadata for the components in your Software Catalog is stored as YAML files that live alongside your code in your version control system. The version control repositories can include one or many metadata files. Software Catalog organizes items as entities, which include Components, Resources, and APIs, and other related types. Each entity includes associated metadata such as its owner, type, and other relevant details.

By storing metadata in YAML files alongside the code, you allow Red Hat Developer Hub to process and display this information through a clear, visual interface. With the Software Catalog, you can manage and maintain your software, stay aware of all software available in your ecosystem, and take ownership of your services and tools.

The Overview page for a component provides key information such as links to the source code, documentation, dependencies, and ownership details. You can customize this page with plugins to suit specific needs.

5.1. Adding new components to your Red Hat Developer Hub instance

Prerequisites

Procedure

You can add components to your RHDH instance using the following methods:

  • Register components manually using the GUI or by using your app-config.yaml with the required permissions.
  • Create new components by using Software Templates.
  • Use the bulk import plugin with the required permissions. For more information, see Bulk importing GitHub repositories.

5.1.1. Creating new components in your Red Hat Developer Hub instance

You can create new components in the Software Catalog in your RHDH instance. Red Hat Developer Hub automatically registers all components that developers or platform engineers create using Templates in the Software Catalog.

Prerequisites

Procedure

  1. In your Red Hat Developer Hub navigation menu, click Catalog.
  2. On the Catalog page, click Self-service.

5.1.2. Registering components manually in your RHDH instance

To manually register components in your RHDH instance, create a catalog-info.yaml file and register it with your Red Hat Developer Hub instance. The catalog-info.yaml file contains the metadata you wish to register for your software component.

Prerequisites

Procedure

  1. In the root directory of your software project, create a file named catalog-info.yaml.

    apiVersion: backstage.io/v1alpha1
    kind: Component
    metadata:
        name: _<your_software_component>_
        description: _<software_component_brief_description>_
        tags:
             - example
             - service
        annotations:
             github.com/project-slug: _<repo_link_of_your_component_to_register>_
    spec:
        type: _<your_service>_
        owner: _<your_team_name>_
        lifecycle: _<your_lifecycle>_
  2. Commit the catalog-info.yaml file to the root of your project source code repository.
  3. In your Red Hat Developer Hub navigation menu, go to Catalog > Self-service.
  4. On the Self-service page, click Register Existing Component.
  5. On the Register an existing component page, enter the full URL of the catalog-info.yaml file in your repository. For example: Artist lookup component.
  6. Complete the wizard instructions.

Verification

  • Your software component is listed in the Software Catalog. You can view its details and ensure all the metadata is accurate.

5.2. Updating components in the Software Catalog in your Red Hat Developer Hub instance

You can update components in the Software Catalog in your Red Hat Developer Hub instance.

Prerequisites

Procedure

To update components in the Software Catalog in your Red Hat Developer Hub instance, complete the following steps:

  1. In your Red Hat Developer Hub navigation menu, click Catalog.
  2. Find the software component that you want to edit, under Actions, click the Edit icon.

    Note

    This action redirects you to the YAML file on GitHub.

  3. On your remote repository UI, update your YAML file.

    Note

    After you merge your changes, the updated metadata in the Software Catalog appears after some time.

5.3. Searching and Filtering Software Catalogs by Kind

Procedure

  1. In your Red Hat Developer Hub navigation menu, click Catalog.
  2. On the Catalog page, click the Kind drop-down list.
  3. Select the type of Kind you want to filter.

    Note

    The available filter dropdowns vary based on the Kind you select, displaying options relevant to that specific entity type.

5.4. Searching and Filtering Software Catalog items by using the Filter field

Procedure

  1. In your Red Hat Developer Hub navigation menu, click Catalog.
  2. In the Search box, enter the text you want to use to filter the components.

5.5. Viewing the Software Catalog YAML file in your Red Hat Developer Hub instance

You can view the Software Catalog YAML file in your Red Hat Developer Hub instance. The YAML file displays the metadata for the components in your Software Catalog.

Procedure

To view the Software Catalog YAML file in your Red Hat Developer Hub instance, complete the following steps:

  1. In your Red Hat Developer Hub navigation menu, click Catalog.
  2. Find the software component that you want to view, under Actions, click the View icon.

    Note

    These steps redirect you to the YAML file on your remote repository.

5.6. Starring components in the Software Catalog

You can use the Add to favorites icon to add the software catalogs that you visit regularly to the Starred category.

Procedure

To quickly access the Software Catalogs that you visit regularly, complete the following steps:

  1. In your Red Hat Developer Hub navigation menu, click Catalog.
  2. Find the software component that you want to add as a favorite, under Actions, click the Add to favorites icon.

Verification

  • The starred component is listed under Your Starred Entities on your Home page.

6. Customizing the Learning Paths in Red Hat Developer Hub

In Red Hat Developer Hub, you can configure Learning Paths by hosting the required data externally, and using the built-in proxy to deliver this data rather than the default.

You can provide Learning Paths data from the following sources:

  • A JSON file hosted on a web server, such as GitHub or GitLab.
  • A dedicated service that provides the Learning Paths data in JSON format using an API.

6.1. About Learning Paths

You can use the Learning Paths plugin in Red Hat Developer Hub to integrate customized e-learning content into the developer workflows. By using Learning Paths, you can create a collaborative learning culture, boost productivity, and ensure that teams stay updated with relevant best practices and technologies. The overall purpose is to accelerate onboarding, address skill gaps, ensure regulatory compliance, promote best practices, and facilitate product updates.

6.2. Customizing the Learning Paths by using a hosted JSON file

For ease of use and simplicity, you can configure the Learning Paths by using a hosted JSON file.

Procedure

  1. Publish the JSON file containing your Learning Paths data to a web server, such as GitHub or Gitlab. You can find an example at https://raw.githubusercontent.com/redhat-developer/rhdh/release-1.8/packages/app/public/learning-paths/data.json.
  2. Configure the Developer Hub proxy to access the Learning Paths data from the hosted JSON file, by adding the following to the app-config.yaml file:

    proxy:
      endpoints:
        '/developer-hub':
          target: <target>
          pathRewrite:
            '^/api/proxy/developer-hub/learning-paths': '<learning_path.json>'
          changeOrigin: true
          secure: true
    <target>
    Enter the hosted JSON file base URL, such as https://raw.githubusercontent.com.
    <learning_path.json>

    Enter the hosted JSON file path without the base URL, such as '/redhat-developer/rhdh/main/packages/app/public/learning-paths/data.json'

    Tip

    When also configuring the home page, due to the use of overlapping pathRewrites for both the learning-path and homepage quick access proxies, create the learning-paths configuration (^api/proxy/developer-hub/learning-paths) before you create the homepage configuration (^/api/proxy/developer-hub). For example:

    proxy:
      endpoints:
        '/developer-hub':
          target: https://raw.githubusercontent.com/
          pathRewrite:
            '^/api/proxy/developer-hub/learning-paths': '/redhat-developer/rhdh/main/packages/app/public/learning-paths/data.json'
            '^/api/proxy/developer-hub/tech-radar': '/redhat-developer/rhdh/main/packages/app/public/tech-radar/data-default.json'
            '^/api/proxy/developer-hub': '/redhat-developer/rhdh/main/packages/app/public/homepage/data.json'
          changeOrigin: true
          secure: true

6.3. Customizing the Learning Paths by using a customization service

For advanced scenarios, you can host your Red Hat Developer Hub customization service to provide data to all configurable Developer Hub pages, such as the Learning Paths. You can even use a different service for each page.

Procedure

  1. Deploy your Developer Hub customization service on the same OpenShift Container Platform cluster as your Developer Hub instance. You can find an example at red-hat-developer-hub-customization-provider, that provides the same data as default Developer Hub data. The customization service provides a Learning Paths data URL such as: http://<rhdh-customization-provider>/learning-paths.
  2. Configure the Developer Hub proxy to use your dedicated service to provide the Learning Path data, add the following to the app-config.yaml file:

    proxy:
      endpoints:
        '/developer-hub/learning-paths':
          target: <learning_path_data_url>
          changeOrigin: true
          qsecure: true 1
    1
    Change to "false" in case of using self hosted cluster with a self-signed certificate

6.4. Starting and completing lessons in Learning Paths

As a developer, you can start a course and complete the lessons at your own pace.

Prerequisites

  1. You can log in to developers.redhat.com
  2. Your platform engineer has granted you access to the Learning Paths plugin.

Procedure

To start a course in Learning Paths, complete the following steps:

  1. In your Red Hat Developer Hub navigation menu, click Learning Paths.
  2. Select the tile for the course you would like to begin.

    Note

    This action redirects you to the main page of the course in the Red Hat Developers site.

7. Configuring the global header in Red Hat Developer Hub

As an administrator, you can configure the Red Hat Developer Hub global header to create a consistent and flexible navigation bar across your Developer Hub instance. By default, the Developer Hub global header includes the following components:

  • Self-service button provides quick access to a variety of templates, enabling users to efficiently set up services, backend and front-end plugins within Developer Hub
  • Support button that can link an internal or external support page
  • Notifications button displays alerts and updates from plugins and external services
  • Search input field allows users to find services, components, documentation, and other resources within Developer Hub
  • Plugin extension capabilities provide a preinstalled and enabled catalog of available plugins in Developer Hub
  • User profile drop-down menu provides access to profile settings, appearance customization, Developer Hub metadata, and a logout button

7.1. Customizing your Red Hat Developer Hub global header

You can use the red-hat-developer-hub.backstage-plugin-global-header dynamic plugin to extend the global header with additional buttons and customize the order and position of icons and features. Additionally, you can create and integrate your custom dynamic header plugins using the mount points provided by this new header feature, allowing you to further tailor to suit your needs. For more information about enabling dynamic plugins, see Installing and viewing plugins in Red Hat Developer Hub.

  - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-header
    disabled: false
    pluginConfig:
      app:
        sidebar:
          search: false
          settings: false
      dynamicPlugins:
        frontend:
          default.main-menu-items:
            menuItems:
              default.create:
                title: ''
          red-hat-developer-hub.backstage-plugin-global-header: # the default enabled dynamic header plugin
            mountPoints:
              - mountPoint: application/header
                importName: GlobalHeader
                config:
                  position: above-main-content 1
              - mountPoint: global.header/component
                importName: SearchComponent
                config:
                  priority: 100
              - mountPoint: global.header/component
                importName: Spacer
                config:
                  priority: 99
                  props:
                    growFactor: 0
              - mountPoint: global.header/component
                importName: HeaderIconButton
                config:
                  priority: 90
                  props:
                    title: Self-service
                    icon: add
                    to: create
              - mountPoint: global.header/component
                importName: SupportButton
                config:
                  priority: 80
              - mountPoint: global.header/component
                importName: NotificationButton
                config:
                  priority: 70
              - mountPoint: global.header/component
                importName: Divider
                config:
                  priority: 50
              - mountPoint: global.header/component
                importName: ProfileDropdown
                config:
                  priority: 10
              - mountPoint: global.header/profile
                importName: MenuItemLink
                config:
                  priority: 100
                  props:
                    title: Settings
                    link: /settings
                    icon: manageAccounts
              - mountPoint: global.header/profile
                importName: LogoutButton
                config:
                  priority: 10

where:

search
Enter false to hide the Search modal in the sidebar menu. Enter true to display the Search modal in the sidebar menu.
settings
Enter false to hides the Settings button in the sidebar menu. Enter true to display the Settings button in the sidebar menu.
default.main-menu-items
Enter this field to hide the Self-service button from the sidebar menu. Remove this field to display the Self-service button in the sidebar menu.
position
Enter above-main-content to position the header above the main content. Enter above-sidebar to position the header above the sidebar.

To extend the functionality of the default global header, include any of the following attributes in your global header entry:

mountPoint
Specifies the location of the header. Use application/header to specify it as a global header. You can configure several global headers at different positions by adding entries to the mountPoints field.
importName

Specifies the component exported by the global header plugin.

The red-hat-developer-hub.backstage-plugin-global-header package (enabled by default) offers the following header components as possible mount point values:

  • SearchComponent: Adds a search bar (enabled by default).
  • Spacer: Adds spacing in the header to position buttons at the end. Useful when you disable SearchComponent.
  • HeaderIconButton: Adds an icon button. By default, the Self-service icon button remains enabled.
  • SupportButton: Adds a Support icon button, allowing users to configure a link to an internal or external page. Enabled by default but requires additional configuration to display.
  • NotificationButton: Adds a Notifications icon button to display unread notifications in real time and navigate to the Notifications page. Enabled by default (requires the notifications plugin).
  • Divider: Adds a vertical divider. By default, a divider appears between the profile dropdown and other header components.
  • ProfileDropdown: Adds a profile dropdown showing the logged-in user’s name. By default, it contains two menu items.
  • MenuItemLink: Adds a link item in a dropdown menu. By default, the profile dropdown includes a link to the Settings page.
  • LogoutButton: Adds a logout button in the profile dropdown (enabled by default).
  • CreateDropdown: Adds a Self-service dropdown button (disabled by default). The menu items are configurable.
  • SoftwareTemplatesSection: Adds a list of software template links to the Self-service dropdown menu (disabled by default). You must enable CreateDropdown.
  • RegisterAComponentSection: Adds a link to the Register a Component page in the Self-service dropdown menu (disabled by default). You must enable CreateDropdown.
config.position
Specifies the position of the header. Supported values are above-main-content and above-sidebar.

Prerequisites

  • You must configure the support URL in the app-config.yaml file to display the Support button in the header.
  • You must install the notifications plugin to display the Notifications button in the header.

Procedure

  1. Copy the default configuration and modify the field values to suit your needs. You can adjust the priority value of each header component to control its position. Additionally, you can enable or disable components by adding or removing them from the configuration. To ensure that the remaining header buttons align with the end of the header before the profile dropdown button, set config.props.growFactor to 1 in the Spacer mount point to enable the Spacer component. For example:

    - mountPoint: global.header/component
      importName: Spacer
      config:
        priority: 100
        props:
          growFactor: 1
  2. To use your custom header, you must install it as a dynamic plugin by adding your plugin configuration to your app-config-dynamic.yaml file. For example:

    - package: <npm_or_oci_package-reference>
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            <package_name>:
              mountPoints:
                - mountPoint: application/header
                  importName: <application_header_name>
                  config:
                    position: above-main-content
                - mountPoint: global.header/component
                  importName: <header_component_name>
                  config:
                    priority: 100
                - mountPoint: global.header/component
                  importName: <header_component_name>
                  config:
                    priority: 90

    where:

    <npm_or_oci_package-reference>
    Specifies the package name.
    <application_header_name>
    Specifies the name of the application header. For example: MyHeader
    <header_component_name>

    Specifies the name of the header component. For example: MyHeaderComponent

    Note

    importName is an optional name referencing the value returned by the scaffolder field extension API.

  3. Optional: To disable the global header, set the value of the disabled field to true in your dynamic-plugins.yaml file. For example:

    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-header
      disabled: true

7.2. Mount points for dynamic plugin integration

You can customize the application header in Developer Hub using mount points for dynamic plugins. These mount points give flexibility in configuring the position of the header, its components and dropdown menus. You can create a customized experience with the following enhancements:

application/header
Controls the header position. Use config.position to set placement as either above-main-content or above-sidebar.
global.header/component
Configures header components. Use config.priority to set the order of components, and pass properties (including CSS styles) via config.props.
Self-service button
- mountPoint: global.header/component
  importName: HeaderIconButton
  config:
    priority: 80
    props:
      title: Self-service
      icon: add
      to: create
Spacer element
- mountPoint: global.header/component
  importName: Spacer
  config:
    priority: 99
    props:
      growFactor: 0
Divider element
mountPoints:
  - mountPoint: global.header/component
    importName: Divider
    config:
      priority: 150
global.header/profile

Configures the profile dropdown list when the ProfileDropdown component is enabled.

  • To add a settings link to the profile dropdown, use the following code:

    - mountPoint: global.header/profile
      importName: MenuItemLink
      config:
        priority: 100
        props:
          title: Settings
          link: /settings
          icon: manageAccounts
global.header/create

Configures the create dropdown list when the CreateDropdown component is enabled.

  • To add a section for registering a component, use the following code:

    - mountPoint: global.header/create
      importName: RegisterAComponentSection
      config:
        props:
          growFactor: 0

7.3. Configuring the logo in the global header

You can configure a company logo in the global header of the Red Hat Developer Hub (RHDH) to reflect your company’s branding. CompanyLogo is part of the global header by default and offers full control over the theming, navigation behavior, sizing, and fallback options.

This component supports the following props, which are provided through configuration:

  • logo: The base64 encoded logo image.
  • to: The redirect path for when users click the logo is '/catalog'.
  • width: The logo width is optional and defaults to 150 px.
  • height: The logo height is optional and defaults to 40 px.

Procedure

  1. To display a custom company logo in the global header, update the configuration with a mount point for CompanyLogo:

    # ...rest of the global header configuration
    red-hat-developer-hub.backstage-plugin-global-header:
      mountPoints:
        - mountPoint: application/header
          importName: GlobalHeader
          config:
            # Supported values: above-main-content | above-sidebar
            position: above-main-content
    
        - mountPoint: global.header/component
          importName: CompanyLogo
          config:
            priority: 200
            props:
              # Path to navigate when users click the logo:
              to: '/catalog'
              width: 300
              height: 200
              logo: <string> or <object> # Logo can be a base64 string or theme-specific object
                # Example 1: Single logo for all themes
                # logo: "<base64_encoded_images>"
    
                # Example 2: Theme-specific logos
                # logo:
                    dark: 'data:image/png;base64,...' # Used in dark theme
                    light: 'data:image/png;base64,...' # Used in light theme
  2. (Optional) If you do not provide logo props to the CompanyLogo component, the component instead uses values defined under app.branding in your app-config.yaml file. You can configure the CompanyLogo as shown in the following configuration:

    app:
      branding:
        fullLogoWidth: 220  # Fallback width
        fullLogo: <string> or <object> #fullLogo can be a base64 string or theme-specific object
    
        # Example 1: Single logo for all themes
        #fullLogo: "<base64_encoded_image>
        # Example 2: Theme-specific logos
        #fullLogo:
            dark: 'data:image/png;base64,...' # Used in dark theme
            light: 'data:image/png;base64,...' # Used in light theme

    CompanyLogo uses the following configuration elements to control fallback and sizing behavior:

    • Logo source priority

      • The component selects the logo source in the following order:

        First, CompanyLogo props (logo, logo.light, logo.dark), then, app.branding.fullLogo. If you do not provide a logo through either, the component displays the default Developer Hub theme-specific logo.

    • Logo width priority

      • The component applies the first available value from props.width, then app.branding.fullLogoWidth from app-config.yaml. If you do not specify the width using either, the component applies a default width (150 px).
Note

CompanyLogo preserves the images aspect ratio and never crops or distorts it. If the configured width results in a height greater than the maximum allowed (default: 40px), the image is automatically scaled down. As a result, adjusting only the width may not visibly change the logo unless the height is also configured.

Increasing the logo height increases the height of the global header. The component first applies the value from props.height. If you do not specify the height, the component applies a default height (40px).

Verification

  1. The logo appears correctly in the global header.
  2. Click the logo to confirm it redirects to the path you defined in props.to.
  3. Toggle between light and dark themes to ensure the correct logo loads in each.
  4. (Optional) Temporarily remove the CompanyLogo props to test the fallback to app.branding.fullLogo.

7.4. Enabling logo in the sidebar

You can configure a logo in the sidebar of the Red Hat Developer Hub (RHDH).

Procedure

  1. To display the logo exclusively in the sidebar, set the value of the app.sidebar.logo parameter to true as shown in the following example:

    app:
      sidebar:
        logo: true
    Note

    To display the logo in only the sidebar, remove the CompanyLogo component from the configuration.

  2. To display the same logo in the sidebar for all themes, update the configuration as shown in the following configuration:

    app:
      sidebar:
        logo: true
      branding:
        fullLogoWidth: 220
        fullLogo: 'data:image/svg+xml;base64,...'
  3. For theme-specific logos, you can configure the sidebar logo as shown in the following configuration:

    app:
      sidebar:
        logo: true
      branding:
        fullLogoWidth: 220
        fullLogo:
          light: 'data:image/svg+xml;base64,...'
          dark: 'data:image/svg+xml;base64,...'

Verification

  1. The logo appears correctly in the sidebar.
  2. Toggle between light and dark themes to ensure the correct logo loads in each.

7.5. Displaying the preferred username in the profile dropdown

You can display the preferred username in the global header profile drop-down list by configuring spec.profile.displayName in the user entity. When not configured, the application falls back to a metadata.title. If neither is configured, it defaults to a user-friendly name generated by the useProfileInfo hook.

Procedure

  1. To configure spec.profile.displayName, use the following code:

    apiVersion: backstage.io/v1alpha1
    kind: User
    metadata:
      # Required unique username
      name: <my_display_name>
      # Optional preferred title
      title: <display_name_title>
    spec:
      profile:
        # Optional preferred display name (highest priority)
        displayName: <my_display_name>
      memberOf: [janus-authors]
  2. To configure metadata.title rather than spec.profile.displayname, use the following code:

    apiVersion: backstage.io/v1alpha1
    kind: User
    metadata:
      # Required unique username
      name: <my_display_name>
      # Optional preferred title
      title: <display_name_title>
    spec:
      memberOf: [janus-authors]
  3. To configure neither spec.profile.displayname or metadata.title, use the following code:

    apiVersion: backstage.io/v1alpha1
    kind: User
    metadata:
      # Required unique username
      name: <my_display_name>
    spec:
      memberOf: [janus-authors]
Note

The application falls back to metadata.name when you do not register the user entity.

8. Configuring a floating action button in Red Hat Developer Hub

You can use the floating action button plugin to configure any action as a floating button in the Developer Hub instance. The floating action button plugin is enabled by default. You can also configure floating action buttons to display as submenu options within the main floating action button by assigning the floating action buttons to the same slot field of your dynamic-plugins.yaml file.

8.1. Configuring a floating action button as a dynamic plugin

You can configure the floating action button as a dynamic plugin to perform actions or open an internal or external link.

Prerequisites

  • You must have sufficient permissions as a platform engineer.

Procedure

To configure a floating action button as a dynamic plugin, complete any of the following tasks:

  • Specify the global.floatingactionbutton/config mount point in your app-config-dynamic.yaml file. For example:

    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            red-hat-developer-hub.backstage-plugin-bulk-import:
              # Start of the floating action button configuration
              mountPoints:
                - mountPoint: global.floatingactionbutton/config
                  importName: BulkImportPage
                  config:
                    slot: 'page-end'
                    icon: <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#e8eaed"><g><rect fill="none" height="24" width="24"/></g><g><path d="M11,7L9.6,8.4l2.6,2.6H2v2h10.2l-2.6,2.6L11,17l5-5L11,7z M20,19h-8v2h8c1.1,0,2-0.9,2-2V5c0-1.1-0.9-2-2-2h-8v2h8V19z"/></g></svg>
                    label: 'Bulk import'
                    toolTip: 'Register multiple repositories in bulk'
                    to: /bulk-import/repositories
              # End of the floating action button configuration
              appIcons:
                - name: bulkImportIcon
                  importName: BulkImportIcon
              dynamicRoutes:
                - path: /bulk-import/repositories
                  importName: BulkImportPage
                  menuItem:
                    icon: bulkImportIcon
                    text: Bulk import
    frontend:mountPoints:importName
    (Required) The import name with an associated component to the mount point.
    frontend:mountPoints:importName:icon
    Use the svg value to display a black BulkImportPage icon.
  • To configure an action as a floating action button that opens an external link, specify the global.floatingactionbutton/config mount point in your dynamic-plugins.yaml file within the backstage-plugin-global-floating-action-button plugin. For example:

    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-floating-action-button
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            red-hat-developer-hub.backstage-plugin-global-floating-action-button:
              mountPoints:
                  - mountPoint: application/listener
                    importName: DynamicGlobalFloatingActionButton
                  - mountPoint: global.floatingactionbutton/config
                    importName: NullComponent
                    config:
                      icon: '<svg viewBox="0 0 250 300" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M200.134 0l55.555 117.514-55.555 117.518h-47.295l55.555-117.518L152.84 0h47.295zM110.08 99.836l20.056-38.092-2.29-8.868L102.847 0H55.552l48.647 102.898 5.881-3.062zm17.766 74.433l-17.333-39.034-6.314-3.101-48.647 102.898h47.295l25-52.88v-7.883z" fill="#40B4E5"/><path d="M152.842 235.032L97.287 117.514 152.842 0h47.295l-55.555 117.514 55.555 117.518h-47.295zm-97.287 0L0 117.514 55.555 0h47.296L47.295 117.514l55.556 117.518H55.555z" fill="#003764"/></svg>'
                      label: 'Quay'
                      showLabel: true
                      toolTip: 'Quay'
                      to: 'https://quay.io'
                  - mountPoint: global.floatingactionbutton/config
                    importName: NullComponent
                    config:
                      icon: github
                      label: 'Git'
                      toolTip: 'Github'
                      to: https://github.com/redhat-developer/rhdh-plugins
    frontend:mountPoints:importName
    Enter the import name with an associated component to the mount point.
    frontend:mountPoints:importName:icon
    (Optional) Enter the icon in Scalable Vector Graphics (SVG) format to display the Quay icon.
  • To configure a floating action button that contains a submenu, define the global.floatingactionbutton/config mount point in the same slot field in your dynamic-plugins.yaml file for multiple actions. The default slot is page-end when not specified. For example:

    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            red-hat-developer-hub.backstage-plugin-bulk-import:
              # Start of fab config
              mountPoints:
                - mountPoint: global.floatingactionbutton/config
                  importName: BulkImportPage
                  config:
                    slot: 'page-end'
                    icon: <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#e8eaed"><g><rect fill="none" height="24" width="24"/></g><g><path d="M11,7L9.6,8.4l2.6,2.6H2v2h10.2l-2.6,2.6L11,17l5-5L11,7z M20,19h-8v2h8c1.1,0,2-0.9,2-2V5c0-1.1-0.9-2-2-2h-8v2h8V19z"/></g></svg>
                    label: 'Bulk import'
                    toolTip: 'Register multiple repositories in bulk'
                    to: /bulk-import/repositories
              # end of fab config
              appIcons:
                - name: bulkImportIcon
                  importName: BulkImportIcon
              dynamicRoutes:
                - path: /bulk-import/repositories
                  importName: BulkImportPage
                  menuItem:
                    icon: bulkImportIcon
                    text: Bulk import
    
    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-floating-action-button
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            red-hat-developer-hub.backstage-plugin-global-floating-action-button:
              mountPoints:
                - mountPoint: application/listener
                  importName: DynamicGlobalFloatingActionButton
                - mountPoint: global.floatingactionbutton/config
                  importName: NullComponent
                  config:
                    icon: github
                    label: 'Git'
                    toolTip: 'Github'
                    to: https://github.com/redhat-developer/rhdh-plugins
                - mountPoint: global.floatingactionbutton/config
                  importName: NullComponent
                  config:
                    icon: '<svg viewBox="0 0 250 300" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M200.134 0l55.555 117.514-55.555 117.518h-47.295l55.555-117.518L152.84 0h47.295zM110.08 99.836l20.056-38.092-2.29-8.868L102.847 0H55.552l48.647 102.898 5.881-3.062zm17.766 74.433l-17.333-39.034-6.314-3.101-48.647 102.898h47.295l25-52.88v-7.883z" fill="#40B4E5"/><path d="M152.842 235.032L97.287 117.514 152.842 0h47.295l-55.555 117.514 55.555 117.518h-47.295zm-97.287 0L0 117.514 55.555 0h47.296L47.295 117.514l55.556 117.518H55.555z" fill="#003764"/></svg>'
                    label: 'Quay'
                    showLabel: true
                    toolTip: 'Quay'
                    to: 'https://quay.io'
    frontend:mountPoints:importName
    (Required) The import name with an associated component to the mount point.
  • To configure a floating action button to display only on specific pages, configure the global.floatingactionbutton/config mount point in the backstage-plugin-global-floating-action-button plugin and set the visibleOnPaths property as shown in the following example:

    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            red-hat-developer-hub.backstage-plugin-bulk-import:
              # start of fab config
              mountPoints:
                - mountPoint: global.floatingactionbutton/config
                  importName: BulkImportPage 1
                  config:
                    slot: 'page-end'
                    icon: <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#e8eaed"><g><rect fill="none" height="24" width="24"/></g><g><path d="M11,7L9.6,8.4l2.6,2.6H2v2h10.2l-2.6,2.6L11,17l5-5L11,7z M20,19h-8v2h8c1.1,0,2-0.9,2-2V5c0-1.1-0.9-2-2-2h-8v2h8V19z"/></g></svg>
                    label: 'Bulk import'
                    toolTip: 'Register multiple repositories in bulk'
                    to: /bulk-import/repositories
                    visibleOnPaths: ['/catalog', '/settings']
              # end of fab config
              appIcons:
                - name: bulkImportIcon
                  importName: BulkImportIcon
              dynamicRoutes:
                - path: /bulk-import/repositories
                  importName: BulkImportPage
                  menuItem:
                    icon: bulkImportIcon
                    text: Bulk import
    frontend:mountPoints:importName
    Enter the import name with an associated component to the mount point.
  • To hide a floating action button on specific pages, configure the global.floatingactionbutton/config mount point in the backstage-plugin-global-floating-action-button plugin and set the excludeOnPaths property as shown in the following example:

    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            red-hat-developer-hub.backstage-plugin-bulk-import:
              # start of fab config
              mountPoints:
                - mountPoint: global.floatingactionbutton/config
                  importName: BulkImportPage 1
                  config:
                    slot: 'page-end'
                    icon: <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#e8eaed"><g><rect fill="none" height="24" width="24"/></g><g><path d="M11,7L9.6,8.4l2.6,2.6H2v2h10.2l-2.6,2.6L11,17l5-5L11,7z M20,19h-8v2h8c1.1,0,2-0.9,2-2V5c0-1.1-0.9-2-2-2h-8v2h8V19z"/></g></svg>
                    label: 'Bulk import'
                    toolTip: 'Register multiple repositories in bulk'
                    to: /bulk-import/repositories
                    excludeOnPaths: ['/bulk-import']
              # end of fab config
              appIcons:
                - name: bulkImportIcon
                  importName: BulkImportIcon
              dynamicRoutes:
                - path: /bulk-import/repositories
                  importName: BulkImportPage
                  menuItem:
                    icon: bulkImportIcon
                    text: Bulk import
    frontend:mountPoints:importName
    Enter the import name with an associated component to the mount point.

8.2. Floating action button parameters

Use the parameters as shown in the following table to configure your floating action button plugin.

Table 1. Floating action button parameters

NameDescriptionTypeDefault valueRequired

slot

Position of the floating action button. Valid values: PAGE_END, BOTTOM_LEFT

enum

PAGE_END

No

label

Name of the floating action button

String

Not applicable

Yes

icon

Icon of the floating action button. Recommended to use filled icons from the Material Design library. You can also use an svg icon. For example: <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#e8eaed"><g><rect fill="none" height="24" width="24"/></g><g><path d="M11,7L9.6,8.4l2.6,2.6H2v2h10.2l-2.6,2.6L11,17l5-5L11,7z M20,19h-8v2h8c1.1,0,2-0.9,2-2V5c0-1.1-0.9-2-2-2h-8v2h8V19z"/></g></svg>

String, React.ReactElement, SVG image icon, HTML image icon

Not applicable

No

showLabel

Display of the label next to your icon

Boolean

Not applicable

No

size

Size of the floating action button

small, medium, large

medium

No

color

Color of the component. It supports both default and custom theme colors, that are added from the Palette Getting started guide.

default, error, info, inherit, primary, secondary, success, warning

default

No

onClick

Performed action when selecting a floating action button

React.MouseEventHandler

Not applicable

No

to

Link that opens when selecting a floating action button

String

Not applicable

No

toolTip

Text that appears when hovering over a floating action button

String

Not applicable

No

priority

Order of the floating action buttons displayed in the submenu. A larger value means higher priority.

number

Not applicable

No

visibleOnPaths

Display floating action button on the specified paths

string[]

Display floating action button on all paths

No

excludeOnPaths

Hide floating action button on the specified paths

string[]

Display floating action button on all paths

No

Note

If multiple floating button actions are assigned to the same slot value, the floating buttons are displayed as submenu options within the main floating action button.

9. Customizing the Quickstart plugin

9.1. About Quickstarts

The Quickstart plugin provides guided onboarding for adminstrators of Red Hat Developer Hub. It displays a customizable drawer interface with interactive quickstart steps that help users get familiar with the platform.

Note

If RBAC is enabled, Quickstart is only accesible to users with administrator permissions.

The Quickstart plugin is enabled by default and includes the following components:

Set up authentication
Set up secure login credentials to protect your account from unauthorized access.
Configure RBAC
Assign roles and permissions to control who can view, create, or edit resources, ensuring secure and efficient collaboration.
Configure Git
Connect your Git providers, such as GitHub to manage code, automate workflows, and integrate with platform features.
Manage plugins
Browse and install extensions to add features, connect with external tools, and customize your experience.

9.2. Customizing your Red Hat Developer Hub Quickstart

As an administrator, you can configure the Red Hat Developer Hub Quickstart plugin to create customized onboarding for your Developer Hub users.

Prerequisites

You must have administrator permissions.

Procedure

  1. Update your app-config.yaml, as shown in the following code:

    app:
      quickstart:
        - title: 'Welcome to Developer Hub'
          description: 'Learn the basics of navigating the Developer Hub interface'
          icon: 'home'
          cta:
            text: 'Get Started'
            link: '/catalog'
        - title: 'Create Your First Component'
          description: 'Follow our guide to register your first software component'
          icon: 'code'
          cta:
            text: 'Create Component'
            link: '/catalog-import'
        - title: 'Explore Templates'
          description: 'Discover available software templates to bootstrap new projects'
          icon: 'template'
          cta:
            text: 'Browse Templates'
            link: '/create'
    title
    Enter the display title for the quickstart step.
    description
    Enter the brief description of what the step covers.
    icon
    (Optional) Enter the icon identifier (supports Material UI icons).
    cta
    text
    (Optional) Enter the CTA button text.
    link
    (Optional) Enter the CTA target URL or route.

9.2.1. Disabling the Quickstart plugin

The Quickstart plugin is pre-loaded in Developer Hub with basic configuration properties, and enabled by default.

Procedure

  • To disable the Quickstart plugin, set the disabled property to true as shown in the following code:

    global:
      dynamic:
        includes:
          - dynamic-plugins.default.yaml
        plugins:
          - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-quickstart
            disabled: true

9.3. Using Quickstart onboarding steps

You can use the Quickstart onboarding steps to learn more about the administrator features of RHDH.

Prerequisites

  • (Optional) If RBAC is enabled, you must have administrator permissions to access to the Quickstart feature.

Procedure

To start a Quickstart step in Red Hat Developer Hub, complete the following steps:

  1. In your RHDH navigation menu, click the Help (?) icon.
  2. In the dropdown menu, click Quick start.
  3. Select the Quickstart step that you would like to begin.
  4. To close the Quickstart drawer, click Hide.

    About Quickstarts
    Note

    Your overall progress is tracked and displayed as a progress bar and a progress percentage in the Quickstart footer.

10. Customizing the Tech Radar page in Red Hat Developer Hub

In Red Hat Developer Hub, the Tech Radar page is provided by the tech-radar dynamic plugin, which is disabled by default. For information about enabling dynamic plugins in Red Hat Developer Hub see Configuring dynamic plugins.

In Red Hat Developer Hub, you can configure Learning Paths by passing the data into the app-config.yaml file as a proxy. The base Tech Radar URL must include the /developer-hub/tech-radar proxy.

Note

Due to the use of overlapping pathRewrites for both the tech-radar and homepage quick access proxies, you must create the tech-radar configuration (^api/proxy/developer-hub/tech-radar) before you create the homepage configuration (^/api/proxy/developer-hub).

For more information about customizing the Home page in Red Hat Developer Hub, see Customizing the Home page in Red Hat Developer Hub.

You can provide data to the Tech Radar page from the following sources:

  • JSON files hosted on GitHub or GitLab.
  • A dedicated service that provides the Tech Radar data in JSON format using an API.

10.1. Customizing the Tech Radar page by using a JSON file

For ease of use and simplicity, you can configure the Tech Radar page by using a hosted JSON file.

Prerequisites

  • You have specified the data sources for the Tech Radar plugin in the integrations section of the app-config.yaml file. For example, you have enabled Developer Hub integration with GitHub.
  • You have enabled the ./dynamic-plugins/dist/backstage-community-plugin-tech-radar and /dynamic-plugins/dist/backstage-community-plugin-tech-radar-backend-dynamic plugins.

Procedure

  1. Publish the JSON file containing your Tech Radar data to a web server, such as GitHub or Gitlab. You can find an example at https://raw.githubusercontent.com/backstage/community-plugins/main/workspaces/tech-radar/plugins/tech-radar-common/src/sampleTechRadarResponse.json.
  2. Configure Developer Hub to access the Tech Radar data from the hosted JSON files, by adding the following to the app-config.yaml file:

    techRadar:
      url: <tech_radar_data_url>
    <tech_radar_data_url>
    Enter the Tech Radar data hosted JSON URL.

10.2. Customizing the Tech Radar page by using a customization service

For advanced scenarios, you can host your Red Hat Developer Hub customization service to provide data to all configurable Developer Hub pages, such as the Tech Radar page. You can even use a different service for each page.

Prerequisites

  • You have specified the data sources for the Tech Radar plugin in the integrations section of the app-config.yaml file. For example, you have enabled Developer Hub integration with GitHub.
  • You have enabled the ./dynamic-plugins/dist/backstage-community-plugin-tech-radar and /dynamic-plugins/dist/backstage-community-plugin-tech-radar-backend-dynamic plugins.

Procedure

  1. Deploy your Developer Hub customization service on the same OpenShift Container Platform cluster as your Developer Hub instance. You can find an example at red-hat-developer-hub-customization-provider, that provides the same data as default Developer Hub data. The customization service provides a Tech Radar data URL such as: http://<rhdh-customization-provider>/tech-radar.
  2. Add the dedicated service as an allowed host by adding the following code to the app-config.yaml file:

    backend:
       reading:
            allow:
              - host: '<rhdh_customization_provider_base_url>'
    <rhdh_customization_provider_base_url>
    Enter the base URL of your Tech Radar data URL, such as: <rhdh-customization-provider>.
  3. Add the following to the app-config.yaml file:

    techRadar:
        url: <tech_radar_data_url>
    <tech_radar_data_url>
    Enter your Tech Radar data URL, such as: http://<rhdh-customization-provider>/tech-radar.

11. Customizing Red Hat Developer Hub appearance

By modifying the visual aspects of the interface, organizations can align Red Hat Developer Hub with their branding guidelines and improve the overall user experience.

The following default theme configurations are available for Red Hat Developer Hub:

The Red Hat Developer Hub theme
Default theme configurations to make your developer portal look like a standard Red Hat Developer Hub instance. For more information, see Section 11.9, “Default Red Hat Developer Hub theme”
The Backstage theme
Default theme configurations to make your developer portal look like a standard Backstage instance. For more information, see Section 11.10, “Default Backstage theme”

You can change or disable particular parameters in a default theme or create a fully customized theme by modifying the app-config-rhdh.yaml file. From the app-config-rhdh.yaml file, you can customize common theme components, including the following components:

  • Company name and logo
  • Font color, size, and style of text in paragraphs, headings, headers, and buttons
  • Header color, gradient, and shape
  • Button color
  • Navigation indicator color

You can also customize some components from the Developer Hub GUI, such as the theme mode (Light Theme, Dark Theme, or Auto).

11.1. Customizing the theme mode for your Developer Hub instance

You can choose one of the following theme modes for your Developer Hub instance:

  • Light
  • Dark
  • Auto
Note

In Developer Hub, theme configurations are used to change the look and feel of different UI components. So, you might notice changes in different UI components, such as buttons, tabs, sidebars, cards, and tables along with some changes in background color and font used on the RHDH pages.

The default theme mode is Auto, which automatically sets the light or dark theme based on your system preferences.

Prerequisites

  • You are logged in to the Developer Hub web console.

Procedure

  1. From the Developer Hub web console, click Settings.
  2. From the Appearance panel, click Light, Dark, or Auto to change the theme mode.

    custom theme mode 1

11.2. Customizing the branding logo of your Developer Hub instance

You can customize the branding logo of your Developer Hub instance by configuring the branding section in the app-config.yaml file, as shown in the following example:

app:
  branding:
    fullLogo: ${BASE64_EMBEDDED_FULL_LOGO} 1
    iconLogo: ${BASE64_EMBEDDED_ICON_LOGO} 2
fullLogo
Enter the logo on the expanded (pinned) sidebar as a base64 encoded image.
iconLogo

Enter the logo on the collapsed (unpinned) sidebar as a base64 encoded image.

You can format the BASE64_EMBEDDED_FULL_LOGO environment variable as follows:

BASE64_EMBEDDED_FULL_LOGO: "data:_<media_type>_;base64,<base64_data>"

The following example demonstrates how to customize the BASE64_EMBEDDED_FULL_LOGO using the data:_<media_type>_;base64,<base64_data> format:

SVGLOGOBASE64=$(base64 -i logo.svg)
BASE64_EMBEDDED_FULL_LOGO="data:image/svg+xml;base64,$SVGLOGOBASE64"

Replace image/svg+xml with the correct media type for your image (for example, image/png and image/jpeg), and adjust the file extension accordingly. As a result, you can embed the logo directly without referencing an external file.

You can also customize the width of the branding logo by setting a value for the fullLogoWidth field in the branding section, as shown in the following example:

app:
  branding:
    fullLogoWidth: 110px
# ...
fullLogoWidth
The default value for the logo width is 110px. The following units are supported: integer, px, em, rem, percentage.

11.3. About the sidebar menu items for your Developer Hub instance

The sidebar menu in Red Hat Developer Hub consists of two main parts that you can configure:

Dynamic plugin menu items
Your preferences and your active plugins define dynamically one part of the sidebar menu.
Main menu items

The core navigation structure of sidebar is static.

  • Dynamic plugin menu items: These items are displayed beneath the main menu and can be customized based on the plugins installed. The main menu items section is dynamic and can change based on your preferences and installed plugins.

11.3.1. Customizing the sidebar menu items for your Developer Hub instance

Customize the main menu items using the following steps:

Procedure

  1. Open the app-config.yaml file.

    1. To customize the order and parent-child relationships for the main menu items, use the dynamicPlugins.frontend.default.main-menu-items.menuItems field.
    2. For dynamic plugin menu items, use the dynamicPlugins.frontend.<package_name>.menuItems field.

Example app-config.yaml file

dynamicPlugins:
  frontend:
    default.main-menu-items:
        menuItems:
          default.home:
            title: Home
            icon: home
            priority: 100
            enabled: true
          default.my-group:
            title: My Group
            icon: group
            priority: 90
            enabled: true
          default.catalog:
            title: Catalog
            icon: category
            to: catalog
            priority: 80
            enabled: true
          default.apis:
            title: APIs
            icon: extension
            to: api-docs
            priority: 70
            enabled: true
          default.learning-path:
            title: Learning Paths
            icon: school,
            to: learning-paths
            priority: 60
            enabled: true
          default.create:
            title: Self-service
            icon: add
            to: create
            priority: 50
            enabled: true

11.3.2. Configuring a dynamic plugin menu item for your Developer Hub instance

Configure a dynamic plugin menu item using the following step:

Procedure

  • In the app-config.yaml file, update the menuItems section of your <plugin_name> plugin. For example:

    dynamicPlugins:
      frontend:
        _<plugin_name>_:
          menuItems:
            <menu_item_name>:
              icon: # home | group | category | extension | school | _<my_icon>_
              title: _<plugin_page_title>_
              priority: 10
              parent: favorites
              enabled: true
    <plugin_name>
    Enter the plugin name. This name is the same as the scalprum.name key in the package.json file.
    <menu_item_name>
    Enter a unique name in the main sidebar navigation for either a standalone menu item or a parent menu item. If this field specifies a plugin menu item, the name of the menu item must match the name using in the corresponding path in dynamicRoutes. For example, if dynamicRoutes defines path: /my-plugin, then menu_item_name must be defined as my-plugin.
    icon

    (Optional) Enter the icon name. You can use any of the following icons:

    • Default icons, such as home, group, category, extension, and school. To use default icons, set the icon as an (" ") empty string.
    • A custom icon, where <my_icon> specifies the name of your custom icon
    • An SVG icon, such as: icon: <svg width="20px" height="20px" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" fill="#ffffff">…​</svg>
    • An HTML image, such as: icon: https://img.icons8.com/ios-glyphs/20/FFFFFF/shop.png
    title
    (Optional) Enter the menu item title. Omit it when the title is already specified in the dynamicRoutes configuration under menuItem.text. To hide the title from the sidebar, set the title as an (" ") empty string.
    priority
    (Optional) Enter an integer value to set the order in which menu items appear in the sidebar.
    parent
    (Optional) Enter the parent menu item under which the current item is nested. If this field is used, the parent menu item must be defined elsewhere in the menuItems configuration of any enabled plugin. You can define this field for each section.
    enabled
    (Optional) Enter false to hide the menu item from the sidebar. Enter true to display the menu item in the sidebar.
    dynamicPlugins:
      frontend:
        _<package_name>_:
          dynamicRoutes:
            - path: /my-plugin
              module: CustomModule
              importName: FooPluginPage
              menuItem:
                icon: fooIcon
                text: Foo Plugin Page
          menuItems:
            my-plugin:
              priority: 10
              parent: favorites
            favorites:
              icon: favorite
              title: Favorites
              priority: 100
    my-plugin
    Enter the value of the path field in dynamicRoutes.
    priority
    Enter an integer value to set the order in which plugins appear in the parent menu item.
    parent
    Enter the parent menu item id to nest this plugin under, such as favorites.
    favorites
    Configuration for the parent menu item.
    title
    Displays the title name for the parent menu item.

11.3.3. Modifying or adding a custom menu items for your Developer Hub instance

Modify a main menu item or add a custom menu item using the following step:

Procedure

  • In the app-config.yaml file, add a section to the default.main-menu-items > menuItems section. Use the default. prefix to identify the key as a main menu item.

    dynamicPlugins:
      frontend:
        default.main-menu-items:
          menuItems:
            default._<menu_group_parent_item_name>_:
              icon: # home | group | category | extension | school | _<my_icon>_
              title: _<menu_group_parent_title>_
              priority: 10
            default._<menu_item_name>_:
              parent: _<menu_group_parent_item_name>_
              icon:  # home | group | category | extension | school | _<my_icon>_
              title: _<my_menu_title>_
              to: _<path_to_the_menu_target_page>_
              priority: 100
              enabled: true
    default.<menu_group_parent_item_name>
    (Optional) Enter the menu group parent item name to configure static main menu items. If no default.<menu_item_name> has a parent value set, this field is not needed.
    icon
    Enter the menu icon. Required for parent menu items.
    title
    Enter the menu group title. Required for parent menu items.
    priority
    (Optional) Enter the order of this menu item within its menu level.
    default.<menu_item_name>
    Enter the menu item name for which you want to override the default value. Add the default. prefix to identify a main menu item.
    parent
    (Optional) Enter the parent menu item for this item. Required if <menu_item_name> is specified as the child of any menu items.
    icon
    (Optional) Enter the menu icon. To use the default icon, set the icon as an (" ") empty string.
    title
    (Optional) Enter the menu group title. Only required for adding a new custom main menu item. To hide a default main menu item title from the sidebar, set the title as an (" ") empty string.
    to
    (Optional) Enter the path that the menu item navigates to. If it is not set, it defaults to the home page.
    priority
    (Optional) Enter the order of this menu item within its menu level.
    enabled
    (Optional) If this field is used to display the menu item in the sidebar, set the value to true. To hide the menu item from the sidebar, set the value to false.
    default.main-menu-items:
          menuItems:
            default.catalog:
              icon: category
              title: My Catalog
              priority: 5
            default.learning-path:
              title: ''
            default.parentlist:
              title: Overview
              icon: bookmarks
            default.home:
              parent: default.parentlist
            default.references:
              title: References
              icon: school
              to: /references
              enabled: true
    icon
    (Optional) Enter the icon name, such as category, bookmarks`, school, etc. to change the default icon.
    title
    Enter an empty string '' to hide the learning path from the default sidebar.
    default.parentlist
    Enter the parent menu items.
    parent
    Enter the parent menu under which to nest the the menu entry, such as default.parentlist.
    title
    Enter the menu entry name, such as My Catalog, Overview or References.
    to
    Enter the page to redirect to. For example, default.references redirects to the /references page.
    enabled
    (Optional) Enter true to display the menu item in the sidebar. Enter false to hide the menu item from the sidebar.

11.4. Configuring entity tab titles

Red Hat Developer Hub provides a default opinionated tab set for catalog entity views. For consistency with your organization needs, you can rename, reorder, remove, and add tab titles.

Procedure

  • For each tab to modify, enter your desired values in the entityTabs section in your app-config.yaml file:

    upstream:
      backstage:
        appConfig:
          dynamicPlugins:
            frontend:
             <plugin_name>:
                entityTabs:
                  - mountPoint: <mount_point>
                    path: <path>
                    title: <title>
                    priority: <priority>
    <plugin_name>
    Enter the plugin name, such as backstage-community.plugin-topology.
    mountPoint
    Enter the tab mountpoint, such as entity.page.topology.
    path
    Enter the tab path, such as /topology.
    title
    Enter the tab title, such as Topology.
    priority

    Optional.

    To reorder tabs, enter the tab priority, such as 42. Higher priority appears first.

    To remove a tab, enter a negative value, such as -1.

11.5. Configuring entity detail tab layout

Each Red Hat Developer Hub entity detail tab has a default opinionated layout. For consistency with your organization needs, you can change the entity detail tab content when the plugin that contributes the tab content allows a configuration.

Prerequisites

Procedure

  • Copy the plugin default configuration in your app-config.yaml file, and change the layout properties.

    global:
      dynamic:
        plugins:
          - package: <package_location>
            disabled: false
            pluginConfig:
              dynamicPlugins:
                frontend:
                  <plugin_name>:
                    mountPoints:
                      - mountPoint: <mount_point>
                        importName: <import_name>
                        config:
                          layout:
                            gridColumn:
                              lg: span 6
                              xs: span 12
    package
    Enter your package location, such as ./dynamic-plugins/dist/backstage-community-plugin-tekton.
    <plugin_name>
    Enter your plugin name, such as: backstage-community.plugin-tekton.
    mountPoint
    Copy the mount point defined in the plugin default configuration, such as: entity.page.ci/cards.
    importName
    Copy the import name defined in the plugin default configuration, such as: TektonCI.
    layout
    Enter your layout configuration. The tab content is displayed in a responsive grid that uses a 12 column-grid and supports different breakpoints (xs, sm, md, lg, xl) that can be specified for a CSS property, such as gridColumn. The example uses 6 of the 12 columns to show two Tekton CI cards side-by-side on large (lg) screens (span 6 columns) and show them among themselves (xs and above span 12 columns).

11.6. Customizing the theme mode color palettes for your Developer Hub instance

You can customize the color palettes of the light and dark theme modes in your Developer Hub instance by configuring the light.palette and dark.palette parameters in the branding.theme section of the app-config.yaml file, as shown in the following example:

app:
  branding:
    theme:
      light:
        palette:
          primary:
            main: <light_primary_color>
          navigation:
            indicator: <light_indicator_color>
        pageTheme:
          default:
            backgroundColor: [<light_background_color_1>, <light_background_color_2>]
      dark:
        palette:
          primary:
            main: <dark_primary_color>
          navigation:
            indicator: <dark_indicator_color>
        pageTheme:
          default:
            backgroundColor: [<dark_background_color_1>, <dark_background_color_2>]
# ...
light|dark

Enter the theme name: light or dark.

palette.primary:main
Enter the palette main primary color, such as #ffffff or white.
palette.navigation:indicator
Enter the palette navigation indicator color, which is a vertical bar that indicates the selected tab in the navigation panel, such as #FF0000 or red.
pageTheme:default:backgroundColor
Enter the default page theme background color, such as #ffffff or white.

11.7. Customizing the page theme header for your Developer Hub instance

You can customize the header color for the light and dark theme modes in your Developer Hub instance by modifying the branding.theme section of the app-config.yaml file. You can also customize the page headers for additional Developer Hub pages, such as the Home, Catalog, and APIs pages.

app:
  branding:
    theme:
      light:
        palette: {}
        pageTheme:
          default:
            backgroundColor: "<default_light_background_color>"
            fontColor: "<default_light_font_color>"
            shape: none
          apis:
            backgroundColor: "<apis_light_background_color>"
            fontColor: "<apis_light_font_color>"
            shape: none
      dark:
        palette: {}
        pageTheme:
          default:
            backgroundColor: "<default_dark_background_color>"
            fontColor: "<default_dark_font_color>"
            shape: none
# ...
light
Enter the theme mode, such as light or dark.
default

Enter the default page theme configuration

backgroundColor
Enter the page header background color, such as #ffffff or white.
fontColor
Enter the page header text color, such as #000000 or black.
shape
Enter the page header pattern, such as wave, round, or none. apis:: Enter the page id to configure, such as apis or home.

11.8. Customizing the font for your Developer Hub instance

You can configure the typography section of the app-config.yaml file to change the default font family and size of the page text, as well as the font family and size of each heading level, as shown in the following example:

app:
  branding:
    theme:
      light:
        typography:
          fontFamily: "Times New Roman"
          htmlFontSize: 11 # smaller is bigger
          h1:
            fontFamily: "Times New Roman"
            fontSize: 40
          h2:
            fontFamily: "Times New Roman"
            fontSize: 30
          h3:
            fontFamily: "Times New Roman"
            fontSize: 30
          h4:
            fontFamily: "Times New Roman"
            fontSize: 30
          h5:
            fontFamily: "Times New Roman"
            fontSize: 30
          h6:
            fontFamily: "Times New Roman"
            fontSize: 30
      dark:
        typography:
          fontFamily: "Times New Roman"
          htmlFontSize: 11 # smaller is bigger
          h1:
            fontFamily: "Times New Roman"
            fontSize: 40
          h2:
            fontFamily: "Times New Roman"
            fontSize: 30
          h3:
            fontFamily: "Times New Roman"
            fontSize: 30
          h4:
            fontFamily: "Times New Roman"
            fontSize: 30
          h5:
            fontFamily: "Times New Roman"
            fontSize: 30
          h6:
            fontFamily: "Times New Roman"
            fontSize: 30
# ...

11.9. Default Red Hat Developer Hub theme

You can use the default Red Hat Developer Hub theme configurations to make your Developer Hub instance look like a standard Red Hat Developer Hub instance. You can also modify the app-config.yaml file to customize or disable particular parameters.

11.9.1. Default Red Hat Developer Hub theme color palette

The app-config.yaml file uses the following configurations for the default Red Hat Developer Hub color palette:

app:
  branding:
    theme:
      light:
        variant: "rhdh"
        mode: "light"
        palette:
          background:
            default: "#F8F8F8"
            paper: "#FFFFFF"
          banner:
            closeButtonColor: "#FFFFFF"
            error: "#E22134"
            info: "#2E77D0"
            link: "#000000"
            text: "#FFFFFF"
            warning: "#FF9800"
          border: "#E6E6E6"
          bursts:
            backgroundColor:
              default: "#7C3699"
            fontColor: "#FEFEFE"
            gradient:
              linear: "linear-gradient(-137deg, #4BB8A5 0%, #187656 100%)"
            slackChannelText: "#ddd"
          errorBackground: "#FFEBEE"
          errorText: "#CA001B"
          gold: "#FFD600"
          highlight: "#FFFBCC"
          infoBackground: "#ebf5ff"
          infoText: "#004e8a"
          link: "#0A6EBE"
          linkHover: "#2196F3"
          mode: "light"
          navigation:
            background: "#222427"
            indicator: "#0066CC"
            color: "#ffffff"
            selectedColor: "#ffffff"
            navItem:
              hoverBackground: "#3c3f42"
            submenu:
              background: "#222427"
          pinSidebarButton:
            background: "#BDBDBD"
            icon: "#181818"
          primary:
            main: "#0066CC"
          secondary:
            main: "#8476D1"
          status:
            aborted: "#757575"
            error: "#E22134"
            ok: "#1DB954"
            pending: "#FFED51"
            running: "#1F5493"
            warning: "#FF9800"
          tabbar:
            indicator: "#9BF0E1"
          textContrast: "#000000"
          textSubtle: "#6E6E6E"
          textVerySubtle: "#DDD"
          warningBackground: "#F59B23"
          warningText: "#000000"
          text:
            primary: "#151515"
            secondary: "#757575"
          rhdh:
            general:
              disabledBackground: "#D2D2D2"
              disabled: "#6A6E73"
              searchBarBorderColor: "#E4E4E4"
              formControlBackgroundColor: "#FFF"
              mainSectionBackgroundColor: "#FFF"
              headerBottomBorderColor: "#C7C7C7"
              cardBackgroundColor: "#FFF"
              sidebarBackgroundColor: "#212427"
              cardBorderColor: "#C7C7C7"
              tableTitleColor: "#181818"
              tableSubtitleColor: "#616161"
              tableColumnTitleColor: "#151515"
              tableRowHover: "#F5F5F5"
              tableBorderColor: "#E0E0E0"
              tableBackgroundColor: "#FFF"
              tabsBottomBorderColor: "#D2D2D2"
              contrastText: "#FFF"
            primary:
              main: "#0066CC"
              focusVisibleBorder: "#0066CC"
            secondary:
              main: "#8476D1"
              focusVisibleBorder: "#8476D1"
            cards:
              headerTextColor: "#151515"
              headerBackgroundColor: "#FFF"
              headerBackgroundImage: "none"

      dark:
        variant: "rhdh"
        mode: "dark"
        palette:
          background:
            default: "#333333"
            paper: "#424242"
          banner:
            closeButtonColor: "#FFFFFF"
            error: "#E22134"
            info: "#2E77D0"
            link: "#000000"
            text: "#FFFFFF"
            warning: "#FF9800"
          border: "#E6E6E6"
          bursts:
            backgroundColor:
              default: "#7C3699"
            fontColor: "#FEFEFE"
            gradient:
              linear: "linear-gradient(-137deg, #4BB8A5 0%, #187656 100%)"
            slackChannelText: "#ddd"
          errorBackground: "#FFEBEE"
          errorText: "#CA001B"
          gold: "#FFD600"
          highlight: "#FFFBCC"
          infoBackground: "#ebf5ff"
          infoText: "#004e8a"
          link: "#9CC9FF"
          linkHover: "#82BAFD"
          mode: "dark"
          navigation:
            background: "#0f1214"
            indicator: "#0066CC"
            color: "#ffffff"
            selectedColor: "#ffffff"
            navItem:
              hoverBackground: "#3c3f42"
            submenu:
              background: "#0f1214"
          pinSidebarButton:
            background: "#BDBDBD"
            icon: "#404040"
          primary:
            main: "#1FA7F8"
          secondary:
            main: "#B2A3FF"
          status:
            aborted: "#9E9E9E"
            error: "#F84C55"
            ok: "#71CF88"
            pending: "#FEF071"
            running: "#3488E3"
            warning: "#FFB84D"
          tabbar:
            indicator: "#9BF0E1"
          textContrast: "#FFFFFF"
          textSubtle: "#CCCCCC"
          textVerySubtle: "#727272"
          warningBackground: "#F59B23"
          warningText: "#000000"

          rhdh:
            general:
              disabledBackground: "#444548"
              disabled: "#AAABAC"
              searchBarBorderColor: "#57585a"
              formControlBackgroundColor: "#36373A"
              mainSectionBackgroundColor: "#0f1214"
              headerBottomBorderColor: "#A3A3A3"
              cardBackgroundColor: "#292929"
              sidebarBackgroundColor: "#1b1d21"
              cardBorderColor: "#A3A3A3"
              tableTitleColor: "#E0E0E0"
              tableSubtitleColor: "#E0E0E0"
              tableColumnTitleColor: "#E0E0E0"
              tableRowHover: "#0f1214"
              tableBorderColor: "#515151"
              tableBackgroundColor: "#1b1d21"
              tabsBottomBorderColor: "#444548"
              contrastText: "#FFF"
            primary:
              main: "#1FA7F8"
              focusVisibleBorder: "#ADD6FF"
            secondary:
              main: "#B2A3FF"
              focusVisibleBorder: "#D0C7FF"
            cards:
              headerTextColor: "#FFF"
              headerBackgroundColor: "#0f1214"
              headerBackgroundImage: "none"

Alternatively, you can use the following variant and mode values in the app-config.yaml file to apply the previous default configuration:

app:
  branding:
    theme:
      light:
        variant: "rhdh"
        mode: "light"
      dark:
        variant: "rhdh"
        mode: "dark"

11.9.2. Default Red Hat Developer Hub page themes

The default Developer Hub header color is white in light mode and black in dark mode, as shown in the following app-config.yaml file configuration:

app:
  branding:
    theme:
      light:
        palette: {}
        defaultPageTheme: default
        pageTheme:
          default:
            backgroundColor: "#ffffff"
      dark:
        palette: {}
        defaultPageTheme: default
        pageTheme:
          default:
            backgroundColor: "#0f1214"

11.10. Default Backstage theme

You can use the default Backstage theme configurations to make your Developer Hub instance look like a standard Backstage instance. You can also modify the app-config.yaml file to customize or disable particular parameters.

11.10.1. Default Backstage theme color palette

The app-config.yaml file uses the following configurations for the default Backstage color palette:

app:
  branding:
    theme:
      light:
        variant: "backstage"
        mode: "light"
        palette:
          background:
            default: "#F8F8F8"
            paper: "#FFFFFF"
          banner:
            closeButtonColor: "#FFFFFF"
            error: "#E22134"
            info: "#2E77D0"
            link: "#000000"
            text: "#FFFFFF"
            warning: "#FF9800"
          border: "#E6E6E6"
          bursts:
            backgroundColor:
              default: "#7C3699"
            fontColor: "#FEFEFE"
            gradient:
              linear: "linear-gradient(-137deg, #4BB8A5 0%, #187656 100%)"
            slackChannelText: "#ddd"
          errorBackground: "#FFEBEE"
          errorText: "#CA001B"
          gold: "#FFD600"
          highlight: "#FFFBCC"
          infoBackground: "#ebf5ff"
          infoText: "#004e8a"
          link: "#0A6EBE"
          linkHover: "#2196F3"
          navigation:
            background: "#171717"
            color: "#b5b5b5"
            indicator: "#9BF0E1"
            navItem:
              hoverBackground: "#404040"
            selectedColor: "#FFF"
            submenu:
              background: "#404040"
          pinSidebarButton:
            background: "#BDBDBD"
            icon: "#181818"
          primary:
            main: "#1F5493"
          status:
            aborted: "#757575"
            error: "#E22134"
            ok: "#1DB954"
            pending: "#FFED51"
            running: "#1F5493"
            warning: "#FF9800"
          tabbar:
            indicator: "#9BF0E1"
          textContrast: "#000000"
          textSubtle: "#6E6E6E"
          textVerySubtle: "#DDD"
          warningBackground: "#F59B23"
          warningText: "#000000"

      dark:
        variant: "backstage"
        mode: "dark"
        palette:
          background:
            default: "#333333"
            paper: "#424242"
          banner:
            closeButtonColor: "#FFFFFF"
            error: "#E22134"
            info: "#2E77D0"
            link: "#000000"
            text: "#FFFFFF"
            warning: "#FF9800"
          border: "#E6E6E6"
          bursts:
            backgroundColor:
              default: "#7C3699"
            fontColor: "#FEFEFE"
            gradient:
              linear: "linear-gradient(-137deg, #4BB8A5 0%, #187656 100%)"
            slackChannelText: "#ddd"
          errorBackground: "#FFEBEE"
          errorText: "#CA001B"
          gold: "#FFD600"
          highlight: "#FFFBCC"
          infoBackground: "#ebf5ff"
          infoText: "#004e8a"
          link: "#9CC9FF"
          linkHover: "#82BAFD"
          mode: "dark"
          navigation:
            background: "#424242"
            color: "#b5b5b5"
            indicator: "#9BF0E1"
            navItem:
              hoverBackground: "#404040"
            selectedColor: "#FFF"
            submenu:
              background: "#404040"
          pinSidebarButton:
            background: "#BDBDBD"
            icon: "#404040"
          primary:
            dark: "#82BAFD"
            main: "#9CC9FF"
          secondary:
            main: "#FF88B2"
          status:
            aborted: "#9E9E9E"
            error: "#F84C55"
            ok: "#71CF88"
            pending: "#FEF071"
            running: "#3488E3"
            warning: "#FFB84D"
          tabbar:
            indicator: "#9BF0E1"
          textContrast: "#FFFFFF"
          textSubtle: "#CCCCCC"
          textVerySubtle: "#727272"
          warningBackground: "#F59B23"
          warningText: "#000000"

Alternatively, you can use the following variant and mode values in the app-config.yaml file to apply the previous default configuration:

app:
  branding:
    theme:
      light:
        variant: "backstage"
        mode: "light"
      dark:
        variant: "backstage"
        mode: "dark"

11.10.2. Default Backstage page themes

The default Backstage header color is white in light mode and black in dark mode, as shown in the following app-config.yaml file configuration:

app:
  branding:
    theme:
      light:
        palette: {}
        defaultPageTheme: default
        pageTheme:
          default:
            backgroundColor: ['#005B4B'] # teal
            fontColor: '#ffffff'
            shape: wave
          documentation:
            backgroundColor: ['#C8077A', '#C2297D'] # pinkSea
            fontColor: '#ffffff'
            shape: wave2
          tool:
            backgroundColor: ['#8912CA', '#3E00EA'] # purpleSky
            fontColor: '#ffffff'
            shape: round
          service:
            backgroundColor: ['#006D8F', '#0049A1'] # marineBlue
            fontColor: '#ffffff'
            shape: wave
          website:
            backgroundColor: ['#0027AF', '#270094'] # veryBlue
            fontColor: '#ffffff'
            shape: wave
          library:
            backgroundColor: ['#98002B', '#8D1134'] # rubyRed
            fontColor: '#ffffff'
            shape: wave
          other:
            backgroundColor: ['#171717', '#383838'] # darkGrey
            fontColor: '#ffffff'
            shape: wave
          app:
            backgroundColor: ['#BE2200', '#A41D00'] # toastyOrange
            fontColor: '#ffffff'
            shape: shapes.wave
          apis:
            backgroundColor: ['#005B4B'] # teal
            fontColor: '#ffffff'
            shape: wave2
          card:
            backgroundColor: ['#4BB8A5', '#187656'] # greens
            fontColor: '#ffffff'
            shape: wave

      dark:
        palette: {}
        defaultPageTheme: default
        pageTheme:
          default:
            backgroundColor: ['#005B4B'] # teal
            fontColor: '#ffffff'
            shape: wave
          documentation:
            backgroundColor: ['#C8077A', '#C2297D'] # pinkSea
            fontColor: '#ffffff'
            shape: wave2
          tool:
            backgroundColor: ['#8912CA', '#3E00EA'] # purpleSky
            fontColor: '#ffffff'
            shape: round
          service:
            backgroundColor: ['#006D8F', '#0049A1'] # marineBlue
            fontColor: '#ffffff'
            shape: wave
          website:
            backgroundColor: ['#0027AF', '#270094'] # veryBlue
            fontColor: '#ffffff'
            shape: wave
          library:
            backgroundColor: ['#98002B', '#8D1134'] # rubyRed
            fontColor: '#ffffff'
            shape: wave
          other:
            backgroundColor: ['#171717', '#383838'] # darkGrey
            fontColor: '#ffffff'
            shape: wave
          app:
            backgroundColor: ['#BE2200', '#A41D00'] # toastyOrange
            fontColor: '#ffffff'
            shape: shapes.wave
          apis:
            backgroundColor: ['#005B4B'] # teal
            fontColor: '#ffffff'
            shape: wave2
          card:
            backgroundColor: ['#4BB8A5', '#187656'] # greens
            fontColor: '#ffffff'
            shape: wave

11.11. Loading a custom Developer Hub theme by using a dynamic plugin

You can load a custom Developer Hub theme from a dynamic plugin.

Procedure

  1. Export a theme provider function in your dynamic plugin, for example:

    Sample myTheme.ts fragment

    import { lightTheme } from './lightTheme'; // some custom theme
    import { UnifiedThemeProvider } from '@backstage/theme';
    export const lightThemeProvider = ({ children }: { children: ReactNode }) => (
      <UnifiedThemeProvider theme={lightTheme} children={children} />
    );

    For more information about creating a custom theme, see Backstage documentation - Creating a Custom Theme.

  2. Configure Developer Hub to load the theme in the UI by using the themes configuration field:

    app-config.yaml fragment

    dynamicPlugins:
      frontend:
        example.my-custom-theme-plugin:
          themes:
            - id: light
              title: Light
              variant: light
              icon: someIconReference
              importName: lightThemeProvider

    id
    Enter your theme ID, such as my_theme. Enter dark to override the default Developer Hub dark theme. Enter light to override the default Developer Hub light theme.

Verification

  • The theme is available in the Developer Hub Settings page.

11.12. Custom component options for your Developer Hub instance

There are two component variants that you can use to customize various components of your Developer Hub theme:

  • Patternfly
  • MUI

In addition to assigning a component variant to each parameter in the light or dark theme mode configurations, you can toggle the rippleEffect on or off.

The following code shows the options that you can use in the app-config.yaml file to configure the theme components for your Developer Hub instance:

app:
  branding:
    theme:
      light:
        options:
          rippleEffect: off / on
          paper: patternfly / mui
          buttons: patternfly / mui
          inputs: patternfly / mui
          accordions: patternfly / mui
          sidebars: patternfly / mui
          pages: patternfly / mui
          headers: patternfly / mui
          toolbars: patternfly / mui
          dialogs: patternfly / mui
          cards: patternfly / mui
          tables: patternfly / mui
          tabs: patternfly / mui
      dark:
        options:
          rippleEffect: off / on
          paper: patternfly / mui
          buttons: patternfly / mui
          inputs: patternfly / mui
          accordions: patternfly / mui
          sidebars: patternfly / mui
          pages: patternfly / mui
          headers: patternfly / mui
          toolbars: patternfly / mui
          dialogs: patternfly / mui
          cards: patternfly / mui
          tables: patternfly / mui
          tabs: patternfly / mui

12. Customizing the Home page

When using the app-config, you can do the following:

  • Customize and extend the default Home page layout with additional cards that appear based on the plugins you have installed and enabled.
  • Change quick access links.
  • Add, reorganize, and remove the following available cards:

    • Search bar
    • Quick access
    • Headline
    • Markdown
    • Placeholder
    • Catalog starred entities
    • Featured docs

12.1. Customizing the Home page cards

As an administrator, you can customize the layout and content of the Home page to create a tailored user experience. This includes integrating various specialized cards into the primary view.

The Home page layout uses a 12-column grid system. You can precisely define the position (x), width (w), and height (h) for each card across multiple screen breakpoints:

  • Extra-large (xl)
  • Large (lg)
  • Medium (md)
  • Small (sm)
  • Extra-small (xs)
  • Extra-extra-small (xxs)

The default Home page is as shown in the following app-config.yaml file configuration:

dynamicPlugins:
  frontend:
    red-hat-developer-hub.backstage-plugin-dynamic-home-page:
      dynamicRoutes:
        - path: /
          importName: DynamicHomePage
      mountPoints:
        - mountPoint: home.page/cards
          importName: SearchBar
          config:
            layouts:
              xl: { w: 10, h: 1, x: 1 }
              lg: { w: 10, h: 1, x: 1 }
              md: { w: 10, h: 1, x: 1 }
              sm: { w: 10, h: 1, x: 1 }
              xs: { w: 12, h: 1 }
              xxs: { w: 12, h: 1 }
        - mountPoint: home.page/cards
          importName: QuickAccessCard
          config:
            layouts:
              xl: { w: 7, h: 8 }
              lg: { w: 7, h: 8 }
              md: { w: 7, h: 8 }
              sm: { w: 12, h: 8 }
              xs: { w: 12, h: 8 }
              xxs: { w: 12, h: 8 }
        - mountPoint: home.page/cards
          importName: CatalogStarredEntitiesCard
          config:
            layouts:
              xl: { w: 5, h: 4, x: 7 }
              lg: { w: 5, h: 4, x: 7 }
              md: { w: 5, h: 4, x: 7 }
              sm: { w: 12, h: 4 }
              xs: { w: 12, h: 4 }
              xxs: { w: 12, h: 4 }

Prerequisites

  • You have administrative access and can modify the app-config.yaml file for dynamic plugin configurations.

Procedure

  • Configure different cards for your Home page in Red Hat Developer Hub as shown in the following code:

    Search

    You can use the SearchBar card to provide essential search functionality directly on the Home page.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: SearchBar
              config:
                layouts:
                  xl: { w: 10, h: 1, x: 1 }
                  lg: { w: 10, h: 1, x: 1 }
                  md: { w: 10, h: 1, x: 1 }
                  sm: { w: 10, h: 1, x: 1 }
                  xs: { w: 12, h: 1 }
                  xxs: { w: 12, h: 1 }
                props:
                  path: /search
                  queryParam: query

    Table 2. Available props

    PropDefaultDescription

    path

    /search

    Override the linked search path if needed

    queryParam

    query

    Override the search query parameter name if needed

    Quick access

    You can use the QuickAccessCard card to function as a customizable shortcut panel.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: QuickAccessCard
              config:
                layouts:
                  xl: { h: 8 }
                  lg: { h: 8 }
                  md: { h: 8 }
                  sm: { h: 8 }
                  xs: { h: 8 }
                  xxs: { h: 8 }
                props:
                  title: Quick Access
                  path: /quickaccess

    Table 3. Available props

    PropDefaultDescription

    title

    Quick Access

    Override the linked search path if needed

    path

    none

    Override the search query parameter name if needed

    Headline

    You can use the Headline card to display important information.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: Headline
              config:
                layouts:
                  xl: { h: 1 }
                  lg: { h: 1 }
                  md: { h: 1 }
                  sm: { h: 1 }
                  xs: { h: 1 }
                  xxs: { h: 1 }
                props:
                  title: Important info

    Table 4. Available props

    PropDefaultDescription

    title

    none

    Title

    Markdown

    You can use the Markdown card to display richly formatted content directly within the Home page layout. This card uses Markdown syntax to present structured information, such as lists and links (documentation and plugin repositories).

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: MarkdownCard
              config:
                layouts:
                  xl: { w: 6, h: 4 }
                  lg: { w: 6, h: 4 }
                  md: { w: 6, h: 4 }
                  sm: { w: 6, h: 4 }
                  xs: { w: 6, h: 4 }
                  xxs: { w: 6, h: 4 }
                props:
                  title: Company links
                  content: |
                    ### RHDH
                    * [Website](https://developers.redhat.com/rhdh/overview)
                    * [Documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub/)
                    * [Janus Plugins](https://github.com/janus-idp/backstage-plugins)
                    * [Backstage Community Plugins](https://github.com/backstage/community-plugins)
                    * [RHDH Plugins](https://github.com/redhat-developer/rhdh-plugins)
                    * [RHDH Showcase](https://github.com/redhat-developer/rhdh)
            - mountPoint: home.page/cards
              importName: Markdown
              config:
                layouts:
                  xl: { w: 6, h: 4, x: 6 }
                  lg: { w: 6, h: 4, x: 6 }
                  md: { w: 6, h: 4, x: 6 }
                  sm: { w: 6, h: 4, x: 6 }
                  xs: { w: 6, h: 4, x: 6 }
                  xxs: { w: 6, h: 4, x: 6 }
                props:
                  title: Important company links
                  content: |
                    ### RHDH
                    * [Website](https://developers.redhat.com/rhdh/overview)
                    * [Documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub/)
                    * [Documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub/)
                    * [Janus Plugins](https://github.com/janus-idp/backstage-plugins)
                    * [Backstage Community Plugins](https://github.com/backstage/community-plugins)
                    * [RHDH Plugins](https://github.com/redhat-developer/rhdh-plugins)
                    * [RHDH Showcase](https://github.com/redhat-developer/rhdh)
    Placeholder

    You can use the Placeholder card as a utility element for reserving space or for layout testing on the Home page.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: Placeholder
              config:
                layouts:
                  xl: { w: 1, h: 1 }
                  lg: { w: 1, h: 1 }
                  md: { w: 1, h: 1 }
                  sm: { w: 1, h: 1 }
                  xs: { w: 1, h: 1 }
                  xxs: { w: 1, h: 1 }
                props:
                  showBorder: true
                  debugContent: '1'
    Catalog starred entities

    You can use the CatalogStarredEntitiesCard card to provide a dedicated space on the Home page for users to view catalog entities that they have marked as starred.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: CatalogStarredEntitiesCard
    Featured docs

    You can use the FeaturedDocsCard card as a way to highlight specific documentation within Red Hat Developer Hub, as it is available for deployment on the Home page.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: FeaturedDocsCard
    EntitySection

    You can use the EntitySection card to create a visually engaging section that highlights catalog entities of various kinds, such as Component, API, Resource, and System.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: EntitySection
              config:
                layouts:
                  xl: { w: 12, h: 6 }
                  lg: { w: 12, h: 6 }
                  md: { w: 12, h: 6 }
                  sm: { w: 12, h: 6 }
                  xs: { w: 12, h: 6 }
                  xxs: { w: 12, h: 14.5 }
    OnboardingSection

    You can use the OnboardingSection card to quickly discover learning resources within RHDH.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: OnboardingSection
              config:
                layouts:
                  xl: { w: 12, h: 5 }
                  lg: { w: 12, h: 5 }
                  md: { w: 12, h: 5 }
                  sm: { w: 12, h: 5 }
                  xs: { w: 12, h: 7 }
                  xxs: { w: 12, h: 12 }
    TemplateSection

    You can use the TemplateSection card to quickly explore and initiate software templates in RHDH.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: TemplateSection
              config:
                layouts:
                  xl: { w: 12, h: 5 }
                  lg: { w: 12, h: 5 }
                  md: { w: 12, h: 5 }
                  sm: { w: 12, h: 5 }
                  xs: { w: 12, h: 5 }
                  xxs: { w: 12, h: 14 }

12.2. Defining the layout of the Red Hat Developer Hub Home page

The Home page uses a 12-column grid to position your cards. You can use the optimal parameters to define the layout of your Developer Hub Home page.

Prerequisites

  • Include the following optimal parameters in each of your breakpoints:

    • width (w)
    • height (h)
    • position (x and y)

Procedure

  • Configure your Developer Hub app-config.yaml configuration file by choosing one of the following options:

    • Use the full space on smaller windows and half of the space on larger windows as follows:
dynamicPlugins:
  frontend:
    red-hat-developer-hub.backstage-plugin-dynamic-home-page:
      mountPoints:
        - mountPoint: home.page/cards
          importName: Placeholder
          config:
            layouts:
              xl: { w: 6, h: 2 }
              lg: { w: 6, h: 2 }
              md: { w: 6, h: 2 }
              sm: { w: 12, h: 2 }
              xs: { w: 12, h: 2 }
              xxs: { w: 12, h: 2 }
            props:
              showBorder: true
              debugContent: a placeholder
  • Show the cards side by side by defining the x parameter as shown in the following example:
dynamicPlugins:
  frontend:
    red-hat-developer-hub.backstage-plugin-dynamic-home-page:
      mountPoints:
        - mountPoint: home.page/cards
          importName: Placeholder
          config:
            layouts:
              xl: { w: 6, h: 2 }
              lg: { w: 6, h: 2 }
              md: { w: 6, h: 2 }
              sm: { w: 12, h: 2 }
              xs: { w: 12, h: 2 }
              xxs: { w: 12, h: 2 }
            props:
              showBorder: true
              debugContent: left
        - mountPoint: home.page/cards
          importName: Placeholder
          config:
            layouts:
              xl: { w: 6, h: 2, x: 6 }
              lg: { w: 6, h: 2, x: 6 }
              md: { w: 6, h: 2, x: 6 }
              sm: { w: 12, h: 2, x: 0 }
              xs: { w: 12, h: 2, x: 0 }
              xxs: { w: 12, h: 2, x: 0 }
            props:
              showBorder: true
              debugContent: right

However, you can see a second card below this card by default.

  • Show the cards in three columns by defining the x parameter as shown in the following example:
dynamicPlugins:
  frontend:
    red-hat-developer-hub.backstage-plugin-dynamic-home-page:
      mountPoints:
        - mountPoint: home.page/cards
          importName: Placeholder
          config:
            layouts:
              xl: { w: 4, h: 2 }
              lg: { w: 4, h: 2 }
              md: { w: 4, h: 2 }
              sm: { w: 6, h: 2 }
              xs: { w: 12, h: 2 }
              xxs: { w: 12, h: 2 }
            props:
              showBorder: true
              debugContent: left
        - mountPoint: home.page/cards
          importName: Placeholder
          config:
            layouts:
              xl: { w: 4, h: 2, x: 4 }
              lg: { w: 4, h: 2, x: 4 }
              md: { w: 4, h: 2, x: 4 }
              sm: { w: 6, h: 2, x: 6 }
              xs: { w: 12, h: 2 }
              xxs: { w: 12, h: 2 }
            props:
              showBorder: true
              debugContent: center
        - mountPoint: home.page/cards
          importName: Placeholder
          config:
            layouts:
              xl: { w: 4, h: 2, x: 8 }
              lg: { w: 4, h: 2, x: 8 }
              md: { w: 4, h: 2, x: 8 }
              sm: { w: 6, h: 2 }
              xs: { w: 12, h: 2 }
              xxs: { w: 12, h: 2 }
            props:
              showBorder: true
              debugContent: right

13. Customizing the Quick access card

To access the Home page in Red Hat Developer Hub, the base URL must include the /developer-hub proxy. You can configure the Home page by passing the data into the app-config.yaml file as a proxy. You can provide data to the Home page from the following sources:

  • JSON files hosted on GitHub or GitLab.
  • A dedicated service that provides the Home page data in JSON format using an API.

13.1. Using hosted JSON files to provide data to the Quick access card

Prerequisites

Procedure

  • To access the data from the JSON files, add the following code to the app-config.yaml Developer Hub configuration file:
  • Add the following code to the app-config.yaml file:

    proxy:
      endpoints:
        # Other Proxies
        # customize developer hub instance
        '/developer-hub':
          target: <DOMAIN_URL> # i.e https://raw.githubusercontent.com/
          pathRewrite:
            '^/api/proxy/developer-hub': <path to json file> # i.e /redhat-developer/rhdh/main/packages/app/public/homepage/data.json
          changeOrigin: true
          secure: true
          # Change to "false" in case of using self hosted cluster with a self-signed certificate
          headers:
    	<HEADER_KEY>: <HEADER_VALUE> # optional and can be passed as needed i.e Authorization can be passed for private GitHub repo and PRIVATE-TOKEN can be passed for private GitLab repo

13.2. Using a dedicated service to provide data to the Quick access card

When using a dedicated service, you can do the following tasks:

  • Use the same service to provide the data to all configurable Developer Hub pages or use a different service for each page.
  • Use the red-hat-developer-hub-customization-provider as an example service, which provides data for both the Home and Tech Radar pages. The red-hat-developer-hub-customization-provider service provides the same data as default Developer Hub data. You can fork the red-hat-developer-hub-customization-provider service repository from GitHub and modify it with your own data, if required.
  • Deploy the red-hat-developer-hub-customization-provider service and the Developer Hub Helm chart on the same cluster.

Prerequisites

Procedure

To use a separate service to provide the Home page data, complete the following steps:

  1. In the Red Hat OpenShift Container Platform web console, click +Add > Import from Git.
  2. Enter the URL of your Git repository into the Git Repo URL field.

    To use the red-hat-developer-hub-customization-provider service, add the URL for the red-hat-developer-hub-customization-provider repository or your fork of the repository containing your customizations.

  3. On the General tab, enter red-hat-developer-hub-customization-provider in the Name field and click Create.
  4. On the Advanced Options tab, copy the value from Target Port.

    Note

    Target Port automatically generates a Kubernetes or OpenShift Container Platform service to communicate with.

  5. Add the following code to the app-config.yaml file:

    proxy:
      endpoints:
        # Other Proxies
        # customize developer hub instance
        '/developer-hub':
          target: ${HOMEPAGE_DATA_URL} 1
          changeOrigin: true
          # Change to "false" in case of using self-hosted cluster with a self-signed certificate
          secure: true
    1 1 1 1
    http://<SERVICE_NAME>:8080, for example, http://rhdh-customization-provider:8080.
    Note

    The red-hat-developer-hub-customization-provider service contains the 8080 port by default. If you are using a custom port, you can specify it with the 'PORT' environmental variable in the app-config.yaml file.

  6. Replace the HOMEPAGE_DATA_URL by adding the URL to rhdh-secrets or by directly replacing it in your custom ConfigMap.
  7. Delete the Developer Hub pod to ensure that the new configurations are loaded correctly.

Verification

  • To view the service, go to the OpenShift Container Platform web console and click Networking > Service.

    Note

    You can also view Service Resources in the Topology view.

  • Ensure that the provided API URL for the Home page returns the data in JSON format as shown in the following example:

    [
      {
        "title": "Dropdown 1",
        "isExpanded": false,
        "links": [
          {
            "iconUrl": "https://imagehost.com/image.png",
            "label": "Dropdown 1 Item 1",
            "url": "https://example.com/"
          },
          {
            "iconUrl": "https://imagehost2.org/icon.png",
            "label": "Dropdown 1 Item 2",
            "url": ""
          }
        ]
      },
      {
        "title": "Dropdown 2",
        "isExpanded": true,
        "links": [
          {
            "iconUrl": "http://imagehost3.edu/img.jpg",
            "label": "Dropdown 2 Item 1",
            "url": "http://example.com"
          }
        ]
      }
    ]
    Note

    If the request call fails or is not configured, the Developer Hub instance falls back to the default local data.

  • If the images or icons do not load, then allowlist them by adding your image or icon host URLs to the content security policy (csp) img-src in your custom ConfigMap as shown in the following example:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: app-config.yaml
    data:
      app-config.yaml: |
        app:
          title: Red Hat Developer Hub
        backend:
          csp:
            connect-src:
              - "'self'"
              - 'http:'
              - 'https:'
            img-src:
              - "'self'"
              - 'data:'
              - <image host url 1>
              - <image host url 2>
              - <image host url 3>
        # Other Configurations

14. Customizing the RHDH Metadata card on the Settings page

The Settings page in Red Hat Developer Hub contains a RHDH Metadata card. By default, the RHDH Metadata card shows the RHDH Version and Backstage Version of your Red Hat Developer Hub instance. When you click the Show more icon, the card expands to also show Upstream, Midstream, and Build Time information.

You can override the default to show custom build information about your Red Hat Developer Hub instance in the card. You can customize the card title as well as the card contents.

Procedure

To customize the RHDH Metadata card, complete the following step:

  • In your app-config.yaml file, configure the buildinfo field. For example:

    buildInfo:
      title: _<metadata_card_title>_
      card:
        TechDocs builder: '_<techdocs_builder>_'
        Authentication provider: '_<authentication_provider>_'
        RBAC: disabled
      full: true

    where

    <metadata_card_title>
    Specifies the title that you want to display on the customized card.
    <techdocs_builder>
    Specifies whether to generate and publish the docs or to only fetch the docs when using the default build strategy. Possible values are local or external. If you want to generate and publish the docs, set the techdocs.builder field to local in your app-config.yaml file. If you only want to fetch the docs without generating and publishing them, set the techdocs.builder field to external.
    <authentication_provider>
    Specifies the authentication provider that you want to use. Example values are GitHub or GitLab.
    full
    Specifies what information is shown on the customized card. Possible values are true or false. If set to true, only the information specified in this configuration is shown on the card. If set to false, the specified information is shown on the card along with the build versions. The default value is true.

Result

The Settings page displays a card with a custom title and custom build information about your Red Hat Developer Hub instance.

15. Localization in Red Hat Developer Hub

15.1. Enabling the localization framework in Developer Hub

Enabling localization enhances accessibility, improves the user experience for a global audience, and assists organizations in meeting language requirements in specific regions.

The language settings of RHDH use English by default. In RHDH 1.8, you can choose to use one of the following supported languages:

  • English (en)
  • French (fr)

Procedure

  1. To enable the localization framework in your RHDH application, add the i18n section to your custom Developer Hub app-config.yaml configuration file:

    app-config.yaml fragment with localization i18n fields

    i18n:
      locales: # List of supported locales. Must include en, otherwise the translation framework will fail to load.
        - en
        - fr
      defaultLocale: en # Optional. Defaults to en if not specified.

15.1.1. Overriding translations

In RHDH 1.8, English and French are the supported languages. You can implement transalations for other languages by using an allTranslations.json file to override the existing translation strings, and updating the i18n section of your app-config.yaml configuration file to include the translation override file.

Prerequisitea

  • You have enabled localization in your RHDH application.

Procedure

  1. In the top user menu, go to Settings > General.
  2. Click on the download link in the Translations panel to download the default English translation strings.
  3. Create the JSON file containing all your translations, for example:

    allTranslations.json fragment with translation string overrides

    {
      "plugin.npm.translation-ref": {
        "en": {
          "infoCard.title": "NPM Packet JSON {{packageName}}"
        },
        "de": {
          "infoCard.title": "NPM Pakettt JSON {{packageName}}"
        },
        "zh": {
          "infoCard.title": "NPM 包 JSON {{packageName}}"
        }
      },
      "catalog-import": {
        "en": {
          "defaultImportPage.headerTitle": "Import an existing Git repository JSON"
        },
        "de": {
          "defaultImportPage.headerTitle": "Ein vorhandenes Git-Repository importieren JSON"
        }
      }
    }

  4. Login to your cluster and create a config map for your translations override strings:

    oc create configmap all-translations --from-file=/<path-to>/allTranslations.json
  5. Update your Developer hub helm chart to mount the above config map in the app’s filesystem

    1. In the helm chart → Root Schema → Backstage chart schema → Backstage parameters → Backstage container additional volume mounts
    2. Select Add Backstage container additional volume mounts and add the following

      MountPath: /opt/app-root/src/translation
      Name: all-translations
    3. Add the translations to the Backstage container additional volumes in the helm chart

      name: all-translations
      configMap:
      	defaultMode: 420
      	name: all-translations
  6. Update the i18n section to your custom Developer Hub app-config.yaml configuration file to include the translation override file:

    app-config.yaml fragment with localization i18n fields

    i18n:
      locales: # List of supported locales. Must include en, otherwise the translation framework will fail to load.
        - en
        - fr
      defaultLocale: en # Optional. Defaults to en if not specified.
      overrides: # List of JSON translation files applied in order (last file wins).  Each file may override/add translations for one or more plugins/locales
        - <path-to>/<overrides-1>.json
        - <path-to>/<overrides-2>.json

15.2. Selecting the language for your Developer Hub instance

You can choose to use one of the following supported languages:

  • English (default)
  • French

Prerequisites

  • You are logged in to the Developer Hub web console.

Procedure

  1. From the Developer Hub web console, click Settings.
  2. From the Appearance panel, click the language dropdown to select your language of choice.

    customize language dropdown

15.2.1. Language persistence

When you change the language in the UI, your preference is saved to storage. On next login or refresh, your chosen language setting is restored. Guest users cannot persist language preferences.

Default language selection uses the following priority order:

  1. Browser language priority: The system first checks the user’s browser language preferences to provide a personalized experience.
  2. Configuration priority: If no browser language matches the supported locales, the defaultLocale from the i18n configuration is used as a fallback.
  3. Fallback priority: If neither browser preferences nor configuration provide a match, defaults to en.

Red Hat Developer Hub automatically saves and restores user language settings across browser sessions. This feature is enabled by default and uses database storage. To opt-out and use browser storage instead, add the following to your app-config.yaml configuration file:

userSettings:
  persistence: browser 1
1
To opt-out and use browser local storage, set this value to browser. Optionally, set this value to database to persist across browsers and devices. This the default setting and does not require this configuration to be set.

15.3. Localization support for custom plugins

15.3.1. Best practices for implementing localization support for custom plugins in RHDH

When you add localization support to your RHDH plugins the following best practices help ensure that you establish a robust, type-safe, and future-proof localization workflow, separating the immutable source text from the organized key structure and ensuring reliable deployment across all targeted languages:

Do not modify original English strings
This preserves the source of truth for all translators, preventing unexpected changes that would invalidate existing translations and ensuring consistency across all versions.
Use flat dot notation in translation files
Flat dot notation, for example page.title, follows the standard i18next library convention, which optimizes runtime lookups and keeps the actual translation values concise and easy to manage for translation services.
Use nested objects in the reference file for TypeScript support
This allows the TypeScript compiler to enforce structural type checking on your translation keys, catching errors during development rather than at runtime.
Test with mocks to ensure translations work correctly
This isolates the translation logic, guaranteeing the correct keys are passed and rendered without relying on a full environment setup or external translation files during unit testing.
Add all languages to your application configuration
This ensures that the RHDH application initializes and loads all necessary language resources at startup, making the locales immediately available for users to select in the UI.

Table 5. Common patterns

Use casePatternExample

Simple text

t('key')

t('page.title')

With variables

t('key', {param})

t('table.topN', {count: '5'})

Dynamic keys

t(config.titleKey as any)

t('cards.overview.title' as any)

15.3.2. Implementing localization support for your custom plugins

You can implement localization support in your custom RHDH plugins so that your plugins are accessible to a diverse, international user base and follow recommended best practices.

Procedure

  1. Create the following translation files in your plugin’s src/translations/ directory:

    src/translations/ref.ts English reference

    import { createTranslationRef } from "@backstage/core-plugin-api/alpha";
    
    export const myPluginMessages = {
     page: {
       title: "My Plugin",
       subtitle: "Plugin description",
     },
     common: {
       exportCSV: "Export CSV",
       noResults: "No results found",
     },
     table: {
       headers: {
         name: "Name",
         count: "Count",
       },
     },
    };
    
    export const myPluginTranslationRef = createTranslationRef({
     id: "plugin.my-plugin",
     messages: myPluginMessages,
    });

    src/translations/de.ts German translation

    import { createTranslationMessages } from "@backstage/core-plugin-api/alpha";
    import { myPluginTranslationRef } from "./ref";
    
    const myPluginTranslationDe = createTranslationMessages({
     ref: myPluginTranslationRef,
     messages: {
       "page.title": "Mein Plugin",
       "page.subtitle": "Plugin-Beschreibung",
       "common.exportCSV": "CSV exportieren",
       "common.noResults": "Keine Ergebnisse gefunden",
       "table.headers.name": "Name",
       "table.headers.count": "Anzahl",
     },
    });
    
    export default myPluginTranslationDe;

    src/translations/fr.ts French translation

    import { createTranslationMessages } from "@backstage/core-plugin-api/alpha";
    import { myPluginTranslationRef } from "./ref";
    
    const myPluginTranslationFr = createTranslationMessages({
     ref: myPluginTranslationRef,
     messages: {
       "page.title": "Mon Plugin",
       "page.subtitle": "Description du plugin",
       "common.exportCSV": "Exporter CSV",
       "common.noResults": "Aucun résultat trouvé",
       "table.headers.name": "Nom",
       "table.headers.count": "Nombre",
     },
    });
    
    export default myPluginTranslationFr;

    src/translations/index.ts Translation resource

    import { createTranslationResource } from "@backstage/core-plugin-api/alpha";
    import { myPluginTranslationRef } from "./ref";
    
    export const myPluginTranslations = createTranslationResource({
     ref: myPluginTranslationRef,
     translations: {
       de: () => import("./de"),
       fr: () => import("./fr"),
     },
    });
    
    export { myPluginTranslationRef };

  2. Create translation hooks file, as follows:

    src/hooks/useTranslation.ts Translation hooks

    import { useTranslationRef } from "@backstage/core-plugin-api/alpha";
    import { myPluginTranslationRef } from "../translations";
    
    export const useTranslation = () => useTranslationRef(myPluginTranslationRef);

  3. Update your plugin components to replace hardcoded strings with translation calls. For example:

    Before (hardcoded):

    const MyComponent = () => {
     return (
       <div>
         <h1>My Plugin</h1>
         <button>Export CSV</button>
       </div>
     );
    };

    After (translated):

    import { useTranslation } from '../hooks/useTranslation';
    
    const MyComponent = () => {
     const { t } = useTranslation();
    
     return (
       <div>
         <h1>{t('page.title')}</h1>
         <button>{t('common.exportCSV')}</button>
       </div>
     );
    };

  4. (Optional) If your content contains variables, use interpolation:

    // In your translation files
    'table.pagination.topN': 'Top {{count}} items'
    
    // In your component
    const { t } = useTranslation();
    const message = t('table.pagination.topN', { count: '10' });
  5. (Optional) If your content contains dynamic translation keys (for example, from your plugin configuration):

    // Configuration object with translation keys
    const CARD_CONFIGS = [
     { id: 'overview', titleKey: 'cards.overview.title' },
     { id: 'details', titleKey: 'cards.details.title' },
     { id: 'settings', titleKey: 'cards.settings.title' },
    ];
    
    // In your component
    const { t } = useTranslation();
    
    const CardComponent = ({ config }) => {
     return (
       <div>
         <h2>{t(config.titleKey as any)}</h2>
         {/* Use 'as any' for dynamic keys */}
       </div>
     );
    };
  6. Export the translation resources

    src/index.ts file fragment

    // Export your plugin
    export { myPlugin } from "./plugin";
    
    // Export translation resources for RHDH
    export { myPluginTranslations, myPluginTranslationRef } from "./translations";

  7. Update your dynamic-plugins.default.yaml file, as follows:

    src/index.ts file fragment

    backstage-community.plugin-my-plugin:
     translationResources:
       - importName: myPluginTranslations
         ref: myPluginTranslationRef

Verification

To verify your translations, create a test mock file. For example:

src/test-utils/mockTranslations.ts Test mock file

import { myPluginMessages } from "../translations/ref";

function flattenMessages(obj: any, prefix = ""): Record<string, string> {
 const flattened: Record<string, string> = {};
 for (const key in obj) {
   if (obj.hasOwnProperty(key)) {
     const value = obj[key];
     const newKey = prefix ? `${prefix}.${key}` : key;
     if (typeof value === "object" && value !== null) {
       Object.assign(flattened, flattenMessages(value, newKey));
     } else {
       flattened[newKey] = value;
     }
   }
 }
 return flattened;
}

const flattenedMessages = flattenMessages(myPluginMessages);

export const mockT = (key: string, params?: any) => {
 let message = flattenedMessages[key] || key;
 if (params) {
   for (const [paramKey, paramValue] of Object.entries(params)) {
     message = message.replace(
       new RegExp(`{{${paramKey}}}`, "g"),
       String(paramValue),
     );
   }
 }
 return message;
};

export const mockUseTranslation = () => ({ t: mockT });

Update your tests

import { mockUseTranslation } from "../test-utils/mockTranslations";

jest.mock("../hooks/useTranslation", () => ({
 useTranslation: mockUseTranslation,
}));

// Your test code...

Legal Notice

Copyright © 2025 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.