{"id":2262,"date":"2024-06-09T17:32:45","date_gmt":"2024-06-09T17:32:45","guid":{"rendered":"https:\/\/www.aviator.co\/blog\/?p=2262"},"modified":"2025-09-23T12:46:41","modified_gmt":"2025-09-23T12:46:41","slug":"how-to-set-up-backstage-with-github-using-typescript-material-ui","status":"publish","type":"post","link":"https:\/\/www.aviator.co\/blog\/how-to-set-up-backstage-with-github-using-typescript-material-ui\/","title":{"rendered":"How to set up Backstage with GitHub using Typescript &amp; Material UI"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"572\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/1-1024x572.png\" alt=\"\" class=\"wp-image-2263\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/1-1024x572.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/1-300x168.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/1-768x429.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/1.png 1463w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Introduction<\/strong><\/h2>\n\n\n\n<p>An <a href=\"https:\/\/www.aviator.co\/blog\/getting-started-with-an-internal-developer-portal\/\" title=\"\">Internal Developer Platform (IDP)<\/a> serves as a centralized hub for developers, providing tools, services, and resources to optimize the development process. It offers a unified interface for managing code, documentation, and infrastructure, thereby enhancing team efficiency and collaboration.<\/p>\n\n\n\n<p>So, in this tutorial, we&#8217;ll explore the hands-on creation of an IDP platform using Backstage, leveraging TypeScript and Material UI, as outlined below:<\/p>\n\n\n\n<p>1. Local Setup and Launch of Backstage<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Understanding Backstage<\/li>\n\n\n\n<li>Prerequisites<\/li>\n\n\n\n<li>Creating Backstage app<\/li>\n\n\n\n<li>derstanding folder structure<\/li>\n\n\n\n<li>Launching &amp; Visualizing a Backstage app<\/li>\n<\/ul>\n\n\n\n<p>2. Customizing Backstage&#8217;s Appearance<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Change the name of the app on the main page<\/li>\n\n\n\n<li>Apply custom Logo<\/li>\n\n\n\n<li>Customize the look and feel of your App<\/li>\n<\/ul>\n\n\n\n<p>3. Integrating GitHub Authentication Plugin<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Built-in Authentication Providers<\/li>\n\n\n\n<li>Integration with GitHub<\/li>\n\n\n\n<li>Add a sign-in option to the front end for GitHub<\/li>\n<\/ul>\n\n\n\n<p>Before we dive into the tutorial, let&#8217;s briefly understand the significance of TypeScript and Material-UI.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>TypeScript<\/strong><\/h3>\n\n\n\n<p>We are using&nbsp;<a href=\"https:\/\/github.com\/microsoft\/TypeScript\">TypeScript<\/a>&nbsp;because, as a superset of JavaScript, it brings static typing, improving productivity and code quality. Its benefits include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Catching errors early in development makes it easier to identify and fix issues.<\/li>\n\n\n\n<li>Enhancing code readability through clear type definitions for variables and functions.<\/li>\n\n\n\n<li>Allowing developers to work faster by providing features like auto-completion and type-checking.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Material UI<\/strong><\/h3>\n\n\n\n<p>We chose&nbsp;<a href=\"https:\/\/github.com\/mui\/material-ui\">Material UI<\/a>&nbsp;because it:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Provides a uniform look across our platform inspired by Google&#8217;s Material Design.<\/li>\n\n\n\n<li>Offers a rich set of ready-made React components, saving time and reducing errors.<\/li>\n\n\n\n<li>Adapts beautifully to different devices and screen sizes, improving user experience.<\/li>\n<\/ul>\n\n\n\n<p>Spotify&#8217;s use of Material-UI and TypeScript in building Backstage has established it as a leading choice for IDP frameworks. These tools have contributed to creating a user-friendly platform supported by a strong open-source community, setting new standards for Internal Developer Platforms.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>1. Local Setup and Launch of Backstage<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">a.&nbsp;<strong>Understanding Backstage<\/strong><\/h3>\n\n\n\n<p>Before setting up Backstage locally, let&#8217;s review its out-of-the-box features. Backstage is an open-source framework for building developer portals powered by a centralized software catalog.<\/p>\n\n\n\n<p>It brings order to your microservices and infrastructure, enabling product teams to ship high-quality code quickly. It consolidates all your infrastructure tools, services, and documentation into a streamlined development environment. Backstage is designed for everyone in the product team, including engineering managers, developers, and platform engineers.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">b.&nbsp;<strong>Prerequisites<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>npm<\/li>\n\n\n\n<li>Yarn<\/li>\n\n\n\n<li>Curl<\/li>\n\n\n\n<li>Wget<\/li>\n\n\n\n<li>Docker<\/li>\n\n\n\n<li>git<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">c.&nbsp;<strong>Creating Backstage App<\/strong><\/h3>\n\n\n\n<p>We will install the&nbsp;<a href=\"https:\/\/github.com\/backstage\/backstage\">Backstage<\/a>&nbsp;standalone app using&nbsp;<code><strong>npx<\/strong><\/code>&nbsp;(Node Package Execute)<code>.<strong><em>npx<\/em><\/strong><\/code>&nbsp;is a CLI tool that comes preinstalled with Node.js. It allows you to run commands directly from npm (Node Package Manager) or other registries.<\/p>\n\n\n\n<p>Running the command will create a new directory containing the Backstage app. The CLI wizard will prompt you to enter the app&#8217;s name, which will be used to create a subdirectory in your current working directory.<\/p>\n\n\n\n<p>Run the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx @backstage\/create-app@latest<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" width=\"1024\" height=\"180\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/npx-backstage-1024x180.png\" alt=\"\" class=\"wp-image-2268\" style=\"width:572px;height:auto\" title=\"image_tooltip\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/npx-backstage-1024x180.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/npx-backstage-300x53.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/npx-backstage-768x135.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/npx-backstage-1536x270.png 1536w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/npx-backstage.png 1806w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>When prompted, enter y.<\/p>\n\n\n\n<p>Enter a name for your IDP app.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" width=\"1024\" height=\"253\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/idp-app-name-1024x253.png\" alt=\"\" class=\"wp-image-2269\" style=\"width:571px;height:auto\" title=\"image_tooltip\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/idp-app-name-1024x253.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/idp-app-name-300x74.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/idp-app-name-768x190.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/idp-app-name-1536x380.png 1536w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/idp-app-name.png 1610w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"863\" height=\"955\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/app-name-2.png\" alt=\"\" class=\"wp-image-2270\" style=\"width:606px;height:auto\" title=\"image_tooltip\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/app-name-2.png 863w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/app-name-2-271x300.png 271w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/app-name-2-768x850.png 768w\" sizes=\"(max-width: 863px) 100vw, 863px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"328\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/idp-created-1024x328.png\" alt=\"\" class=\"wp-image-2271\" style=\"width:674px;height:auto\" title=\"image_tooltip\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/idp-created-1024x328.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/idp-created-300x96.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/idp-created-768x246.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/idp-created.png 1150w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>This will generate all the necessary files and folder structures inside the directory, allowing you to run your app.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">d.&nbsp;<strong>General folder structure<\/strong><\/h3>\n\n\n\n<p>Below is a layout of the files and folders generated when creating an app.<br>app<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u251c\u2500\u2500 app-config.yaml\n\u251c\u2500\u2500 catalog-info.yaml\n\u251c\u2500\u2500 package.json\n\u2514\u2500\u2500 packages\n    \u251c\u2500\u2500 app\n    \u2514\u2500\u2500 backend<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>app-config.yaml:<\/strong>&nbsp;The main configuration file for the app, specifying settings and parameters<\/li>\n\n\n\n<li><strong>catalog-info.yaml:<\/strong>&nbsp;Describes catalog entities for the app, such as components, APIs, resources, and users, defining their metadata and relationships.<\/li>\n\n\n\n<li><strong>package.json:<\/strong>&nbsp;The root-level package.json file for project metadata and dependencies. Avoid adding npm dependencies here; they should be added to the intended workspace folder.<\/li>\n\n\n\n<li><strong>packages\/:<\/strong>&nbsp;Lerna leaf packages or &#8220;workspaces&#8221;. Everything here has to be a separate package.<\/li>\n\n\n\n<li><strong>packages\/app\/:<\/strong>&nbsp;A fully functioning Backstage frontend app, a starting point for exploring Backstage.<\/li>\n\n\n\n<li><strong>packages\/backend\/:<\/strong>&nbsp;Includes backend services for features like Authentication, Software Catalog, Software Templates, and TechDocs.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">e.<strong>Launching &amp; Visualizing a Backstage app<\/strong><\/h3>\n\n\n\n<p>Your Backstage app is now fully installed and ready to run! Navigate to the application directory and start the app using the yarn dev command. This will run both the front end and back end as separate processes.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code><em>yarn dev<\/em><\/code><\/code><\/pre>\n\n\n\n<p>After a brief startup period, you should see the following output in your terminal. Once the front end is built, your browser should automatically open to display the app. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"712\" height=\"198\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/yarn-dev.png\" alt=\"\" class=\"wp-image-2267\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/yarn-dev.png 712w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/yarn-dev-300x83.png 300w\" sizes=\"(max-width: 712px) 100vw, 712px\" \/><\/figure>\n\n\n\n<p>Once the app is up and running, it will be hosted on port 3000. Open any browser and go to\u00a0http:\/\/localhost:3000<\/p>\n\n\n\n<figure class=\"wp-block-image alignwide size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"572\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/backstage-1-1024x572.png\" alt=\"\" class=\"wp-image-2274\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/backstage-1-1024x572.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/backstage-1-300x168.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/backstage-1-768x429.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/backstage-1.png 1440w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>2. Customizing Backstage&#8217;s Appearance<\/strong><\/h2>\n\n\n\n<p>One of Material-UI&#8217;s key advantages is its extensive collection of customizable components and theming options. In this section, we&#8217;ll explore how to leverage Material-UI to enhance the user interface of our IDP, from adjusting the color palette to redesigning header and footer components.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">a. <strong>Change the name of the app on the main page<\/strong><\/h3>\n\n\n\n<p>The first thing you can do is change the app&#8217;s name on the main page.<br>Open&nbsp;<strong>app-config.yml<\/strong>&nbsp;and replace the title content with the below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app:\n  title: My Org IDP\n  baseUrl: <em style=\"background-color: initial; font-family: var(--theme-font-family); font-size: var(--theme-font-size); font-weight: var(--theme-font-weight); letter-spacing: var(--theme-letter-spacing); text-transform: var(--theme-text-transform);\">http:\/\/localhost:3000<\/em><\/code><\/pre>\n\n\n\n<p>Rerun the application. You should now be able to see the new title.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"228\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/new-title-1024x228.png\" alt=\"\" class=\"wp-image-2277\" style=\"width:617px;height:auto\" title=\"image_tooltip\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/new-title-1024x228.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/new-title-300x67.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/new-title-768x171.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/new-title.png 1282w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">b. <strong>Apply Custom Logo<\/strong><\/h3>\n\n\n\n<p>We will now change the default logo to our custom logo.<\/p>\n\n\n\n<p>1. Place your custom logo under folder <code>packages\/app\/src\/components\/Root\/logo\/<\/code><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><\/li>\n<\/ol>\n\n\n\n<p>2. Then, under the Root folder, open&nbsp;<strong>LogoFull.tsx<\/strong>&nbsp;and replace it with the below code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\timport React from 'react';\n\timport MyCustomLogoIcon from '.\/logo\/idp_logo_icon.png';\n\t\n\tconst LogoIcon = () =&gt; {\n\t  return &lt;img width=\"50\" height=\"50\"\n\t src={MyCustomLogoIcon} \/&gt;;\n\t};\n\texport default LogoIcon;\n<\/code><\/pre>\n\n\n\n<p>3. You can also change the favicon icons under the public folder.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"828\" height=\"646\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/favicons.png\" alt=\"\" class=\"wp-image-2278\" style=\"width:395px;height:auto\" title=\"image_tooltip\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/favicons.png 828w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/favicons-300x234.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/favicons-768x599.png 768w\" sizes=\"(max-width: 828px) 100vw, 828px\" \/><\/figure>\n\n\n\n<p>4. Rerun your application to see the changes below.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"961\" height=\"820\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/icons-updated.png\" alt=\"\" class=\"wp-image-2279\" style=\"width:678px;height:auto\" title=\"image_tooltip\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/icons-updated.png 961w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/icons-updated-300x256.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/icons-updated-768x655.png 768w\" sizes=\"(max-width: 961px) 100vw, 961px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">c. <strong>Customize the look and feel of your App.<\/strong><\/h3>\n\n\n\n<p>To customize your Backstage app, you can adjust various elements to fit your branding and design preferences. Here\u2019s an overview of the customization options:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Custom Theme<\/strong>: <span style=\"background-color: transparent; color: var(--theme-text-color); font-family: var(--theme-font-family); font-size: var(--theme-font-size); font-style: var(--theme-font-style, inherit); font-weight: var(--theme-font-weight); letter-spacing: var(--theme-letter-spacing); text-transform: var(--theme-text-transform);\">Define a custom theme by specifying colors, typography, and other design <\/span>elements.<\/li>\n\n\n\n<li><strong>Custom Typography and Fonts<\/strong>: <span style=\"background-color: transparent; color: var(--theme-text-color); font-family: var(--theme-font-family); font-size: var(--theme-font-size); font-style: var(--theme-font-style, inherit); font-weight: var(--theme-font-weight); letter-spacing: var(--theme-letter-spacing); text-transform: var(--theme-text-transform);\">Customize typography settings and integrate custom fonts<\/span>.<\/li>\n\n\n\n<li><strong>Custom Logo and Icons<\/strong>: <span style=\"background-color: transparent; color: var(--theme-text-color); font-family: var(--theme-font-family); font-size: var(--theme-font-size); font-style: var(--theme-font-style, inherit); font-weight: var(--theme-font-weight); letter-spacing: var(--theme-letter-spacing); text-transform: var(--theme-text-transform);\">Replace the default logo and icons with custom ones. You can place your logo and icon files in the appropriate directory and reference them in your components.<\/span><\/li>\n\n\n\n<li><strong>Custom Sidebar and Homepage<\/strong>: <span style=\"background-color: transparent; color: var(--theme-text-color); font-family: var(--theme-font-family); font-size: var(--theme-font-size); font-style: var(--theme-font-style, inherit); font-weight: var(--theme-font-weight); letter-spacing: var(--theme-letter-spacing); text-transform: var(--theme-text-transform);\">Modify the relevant components and configuration files to update the sidebar and homepage.<\/span><\/li>\n\n\n\n<li><strong>Overriding Component Styles<\/strong>: <span style=\"background-color: transparent; color: var(--theme-text-color); font-family: var(--theme-font-family); font-size: var(--theme-font-size); font-style: var(--theme-font-style, inherit); font-weight: var(--theme-font-weight); letter-spacing: var(--theme-letter-spacing); text-transform: var(--theme-text-transform);\">Override styles of Backstage or Material-UI components to achieve specific design goals. You can create custom CSS files or use styled-components to apply custom styles.<\/span><\/li>\n<\/ol>\n\n\n\n<p>For detailed instructions and examples on how to implement these customization options, refer to the documentation link provided:&nbsp;<a href=\"https:\/\/backstage.io\/docs\/getting-started\/app-custom-theme\">Custom Theme &#8211; Documentation<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>3. Integrating GitHub Authentication Plugin<\/strong><\/h2>\n\n\n\n<p>The authentication system in Backstage serves two distinct purposes: user sign-in and identification and access to third-party resources. It is possible to configure Backstage with multiple authentication providers; however, typically, only one provider is used for sign-in, while the others are used to grant access to external resources.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">a. <strong>Built-in Authentication Providers<\/strong><\/h3>\n\n\n\n<p>Backstage comes with many common authentication providers in the core library, including:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Auth0<\/li>\n\n\n\n<li>Atlassian<\/li>\n\n\n\n<li>Azure<\/li>\n\n\n\n<li>Azure Easy Auth<\/li>\n\n\n\n<li>Bitbucket<\/li>\n\n\n\n<li>Bitbucket Server<\/li>\n\n\n\n<li>Cloudflare Access<\/li>\n\n\n\n<li>GitHub<\/li>\n\n\n\n<li>GitLab<\/li>\n\n\n\n<li>Google<\/li>\n\n\n\n<li>Google IAP<\/li>\n\n\n\n<li>Okta<\/li>\n\n\n\n<li>OAuth 2 Custom Proxy<\/li>\n\n\n\n<li>OneLogin<\/li>\n\n\n\n<li>VMware Cloud<\/li>\n<\/ul>\n\n\n\n<p>These built-in providers can handle the authentication flow for specific services, including required scopes, callbacks, etc. Each provider is added similarly to a Backstage app.Without proper authentication, your organization&#8217;s IDP platform lacks crucial functionality. Integrating GitHub authentication enhances security by ensuring only authorized users can access the platform. It also improves usability by allowing developers to use their existing GitHub credentials for seamless login.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">b. <strong>Integration with GitHub<\/strong><\/h3>\n\n\n\n<p>Integrating GitHub with Backstage enables developers to seamlessly access and manage their repositories within the IDP. In this section, we&#8217;ll set up GitHub authentication and configure the necessary plugins to enable GitHub integration in Backstage.<br><br>Now, go to your GitHub account settings for\u00a0<a href=\"https:\/\/github.com\/settings\/applications\/new\">OAuth\u00a0<\/a>App creation.<br><br>The homepage URL should be pointing to the Backstage&#8217;s front end; it should be on your\u00a0http:\/\/localhost:3000.<\/p>\n\n\n\n<p>The Authorization callback URL will point to the auth backend, which will most likely be\u00a0http:\/\/localhost:7007\/api\/auth\/github\/handler\/frame<\/p>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"648\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/new-oauth-1024x648.png\" alt=\"\" class=\"wp-image-2280\" style=\"width:636px;height:auto\" title=\"image_tooltip\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/new-oauth-1024x648.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/new-oauth-300x190.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/new-oauth-768x486.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/new-oauth.png 1257w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Once you click on the Register Application Button, the page should refresh, and you should be able to see the Client ID.<\/p>\n\n\n\n<p>Then click on Generate a new client secret Button:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"305\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/generate-client-secret-1024x305.png\" alt=\"\" class=\"wp-image-2281\" style=\"width:637px;height:auto\" title=\"image_tooltip\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/generate-client-secret-1024x305.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/generate-client-secret-300x89.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/generate-client-secret-768x229.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/generate-client-secret.png 1227w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Copy the&nbsp;<em>Client ID<\/em>&nbsp;and the&nbsp;<em>Client Secret<\/em>.<\/p>\n\n\n\n<p>Now, in the app folder structure, Open&nbsp;<strong>app-config.yaml<\/strong>, and add your <code>clientId<\/code> and <code>clientSecret<\/code> to this file. It should end up looking like this<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"316\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/config-clientId-1024x316.png\" alt=\"\" class=\"wp-image-2282\" style=\"width:643px;height:auto\" title=\"image_tooltip\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/config-clientId-1024x316.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/config-clientId-300x93.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/config-clientId-768x237.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/config-clientId.png 1135w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">c. Add <strong>sign-in option to the front-end for GitHub<\/strong><\/h3>\n\n\n\n<p>Backstage will re-read the configuration. If there are no errors, you can proceed to the final configuration step: changing the sign-in page.<\/p>\n\n\n\n<p>To update the sign-in page, open <code>packages\/app\/src\/App.tsx<\/code> and below the last import line, add the import:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { githubAuthApiRef } from '@backstage\/core-plugin-api';\nimport { SignInPage } from '@backstage\/core-components';<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"450\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/config-imports-1024x450.png\" alt=\"\" class=\"wp-image-2283\" title=\"image_tooltip\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/config-imports-1024x450.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/config-imports-300x132.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/config-imports-768x337.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/config-imports.png 1427w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Now, in the same file, search for&nbsp;<em><code>const app = createApp<\/code><\/em>, and add:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>components: { \n SignInPage: props =&gt; (\n      &lt;SignInPage\n        {...props}\n        auto\n        provider={{\n          id: 'github-auth-provider',\n          title: 'GitHub',\n          message: 'Sign in using GitHub',\n          apiRef: githubAuthApiRef,\n        }}\n      \/&gt;\n    ),\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"684\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/sigin-component-1024x684.png\" alt=\"\" class=\"wp-image-2284\" style=\"width:748px;height:auto\" title=\"image_tooltip\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/sigin-component-1024x684.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/sigin-component-300x200.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/sigin-component-768x513.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/sigin-component.png 1143w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Restart the application from the terminal by stopping it with Ctrl+C and starting with&nbsp;<em>yarn dev<\/em>. Now, you should be welcomed by a login prompt!<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"259\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/login-prompt-1024x259.png\" alt=\"\" class=\"wp-image-2288\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/login-prompt-1024x259.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/login-prompt-300x76.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/login-prompt-768x194.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/login-prompt.png 1232w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Once you click the Sign IN button, see the page below.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"665\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/github-signin-2-1024x665.png\" alt=\"\" class=\"wp-image-2287\" style=\"width:748px;height:auto\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/github-signin-2-1024x665.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/github-signin-2-300x195.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/github-signin-2-768x499.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/github-signin-2.png 1311w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>\u21d2 Click on Sign In, and on the next screen, you can click on Authorize.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"772\" height=\"727\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/authorize-app.png\" alt=\"\" class=\"wp-image-2289\" style=\"width:482px;height:auto\" title=\"image_tooltip\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/authorize-app.png 772w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/authorize-app-300x283.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/authorize-app-768x723.png 768w\" sizes=\"(max-width: 772px) 100vw, 772px\" \/><\/figure>\n\n\n\n<p>At this point you should have a complete setup of GitHub with Backstage, and can configure services in the <a href=\"https:\/\/www.aviator.co\/blog\/what-is-a-service-catalog-and-why-use-one\/\" title=\"\">Service Catalog<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>References<\/strong><\/h2>\n\n\n\n<p>Here is the&nbsp;<a href=\"https:\/\/github.com\/ScaleupInfra\/backstage_integration\">github repo<\/a>, which contains all the changes mentioned in this tutorial.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.aviator.co\/releases\"><img decoding=\"async\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/08\/blog-cta-9Release_CTA.svg\" alt=\"aviator releases\" class=\"wp-image-2489\"\/><\/a><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, we will explore the hands-on creation of IDP platform using Backstage, leveraging Typescript and Material UI, while customizing the styles.<\/p>\n","protected":false},"author":38,"featured_media":2263,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[285],"tags":[104,105],"class_list":["post-2262","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-platform-engineering"],"blocksy_meta":[],"acf":[],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/06\/1.png","post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts\/2262","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/users\/38"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/comments?post=2262"}],"version-history":[{"count":6,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts\/2262\/revisions"}],"predecessor-version":[{"id":3456,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts\/2262\/revisions\/3456"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/media\/2263"}],"wp:attachment":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/media?parent=2262"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/categories?post=2262"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/tags?post=2262"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}