Customizing Skill Exchange
Introduction
We understand that the default terminology within Skill Exchange is not one size fits all. To help adjust Skill Exchange's terminology to fit what makes sense for your organization, we've created and enabled some features that allow you to customize Skill Exchange.
Setting Up Custom Translations
Skill Exchange uses Backstage's internationalization feature to customize the frontend text. You can customize various text elements throughout the application by providing your own translations. All available translation keys are listed below.
Custom translations only affect the frontend text. If you're looking to also customize url feature paths, please refer to the Customizing Skill Exchange Feature Paths section.
import { TranslationBlueprint } from '@backstage/frontend-plugin-api';
import { skillExchangeTranslationRef } from '@spotify/backstage-plugin-skill-exchange/alpha';
const skillExchangeCustomTranslations = TranslationBlueprint.make({
name: 'skill-exchange-custom-translations',
params: {
resource: createTranslationMessages({
ref: skillExchangeTranslationRef,
messages: {
// Your custom translations here
'navigation.hacks': 'Jams',
'homePage.title': 'Find others who can help',
// ... more translations
},
}),
},
});
export const app = createApp({
features: [
createFrontendModule({
pluginId: 'app',
extensions: [
// ... extensions,
skillExchangeCustomTranslations,
// ... other extensions,
],
}),
],
});
Home

# | Key | Default Text |
---|---|---|
1 | navigation.embeds | Embeds |
2 | navigation.mentors | Mentors |
3 | navigation.hacks | Hacks |
4 | homePage.title | Find people who can help |
5 | homePage.search.placeholder | Search for people by discipline, skill, or team |
6 | homePage.cards.embeds.title | Start an embed |
7 | homePage.cards.embeds.details | Discover short-term opportunities to learn from another team or share your expertise. |
8 | homePage.cards.mentors.title | Find mentorships and pairing |
9 | homePage.cards.mentors.details | Problem-solve with a pair or search for the perfect mentor/mentee match. Sometimes the best learning happens one-on-one. |
10 | homePage.cards.hacks.title | Join a hack |
11 | homePage.cards.hacks.details | Find a project to hack on, or a team to get to know. Use your skills to build something fun and expand what's possible. |
Embeds




# | Key | Default Text |
---|---|---|
1 | navigation.embeds | Embeds |
2 | navigation.mentors | Mentors |
3 | navigation.hacks | Hacks |
4 | embedsPage.title | Embeds |
5 | embedsPage.search.placeholder | Search embeds |
6 | embedsPage.search.filters.myEmbeds | My embeds |
7 | embedsPage.cards.chips.embed | Embed |
8 | embedsPage.cards.embedDetails | Embed details |
Mentors




# | Key | Default Text |
---|---|---|
1 | navigation.embeds | Embeds |
2 | navigation.mentors | Mentors |
3 | navigation.hacks | Hacks |
4 | mentorsPage.navigation.events | Events |
5 | mentorsPage.navigation.mentorships | Mentorships |
6 | mentorsPage.mentorships.search.placeholder | Search mentorships |
7 | mentorsPage.mentorships.search.filters.myMentorships | My mentorships |
8 | mentorsPage.mentorships.search.filters.findAMentor | Find a mentor |
9 | mentorsPage.mentorships.search.filters.beAMentor | Be a mentor |
10 | mentorsPage.mentorships.search.filters.lookingToPair | Looking to pair |
11 | mentorsPage.mentorships.results.sections.lookingToPair.title | Looking to pair |
12 | mentorsPage.mentorships.results.sections.offeringToMentor.title | Offering to mentor |
13 | mentorsPage.mentorships.results.sections.lookingForMentor.title | Looking for a mentor |
Hacks







# | Key | Default Text |
---|---|---|
1 | navigation.embeds | Embeds |
2 | navigation.mentors | Mentors |
3 | navigation.hacks | Hacks |
4 | hacksPage.navigation.events | Events |
5 | hacksPage.navigation.hacks | Hacks |
6 | hacksPage.hacks.search.filters.myHacks | My Hacks |
Customizing Skill Exchange Feature Paths
Skill Exchange uses feature paths to determine the url path for each feature. At default, feature paths are set to embeds
, mentors
, and hacks
. You can customize these paths by providing your own feature paths in your backend app-config.yaml
file.
skillExchange:
embedsPath: 'remixes' # default: 'embeds'
mentorsPath: 'pairings' # default: 'mentors'
hacksPath: 'jams' # default: 'hacks'
The example configuration above will change the url paths for each feature to the following:
- Embeds ->
http://localhost:3000/skill-exchange/remixes
- Mentors ->
http://localhost:3000/skill-exchange/pairings
- Hacks ->
http://localhost:3000/skill-exchange/jams
Customizing Skill Exchange Notifications
Skill Exchange supports two notification channels that can be customized to match your organization's communication style and preferences. You can tailor notification messages, formatting, and content for either Backstage's native notification system and/or Slack integration.
Customizing Backstage Notifications
Backstage notifications appear directly within your Backstage instance and can be customized to match your organization's terminology and communication style.
Prerequisites
Before customizing Backstage notifications, you must first enable Backstage notifications. Please refer to the Backstage Notifications setup section for detailed configuration instructions.
Example: Customizing Embed Notifications for Backstage Notifications
The following example shows how to customize embeds notification messages. Since we're only providing a custom embeds message builder, the default message builders for mentors and hacks will continue to be used. For detailed information on available methods and customization options, refer to the EmbedsMessageBuilder, MentorsMessageBuilder, and HacksMessageBuilder documentation.
import { DefaultNotificationEmbedsMessageBuilder } from '@spotify/backstage-plugin-skill-exchange-backend';
import { InquiryMessageArgs } from '@spotify/backstage-plugin-skill-exchange-node/alpha';
export class CustomNotificationEmbedsMessageBuilder extends DefaultNotificationEmbedsMessageBuilder {
// Override other methods as needed
buildInquiryMessage({
postTitle,
sender,
customMessage,
}: InquiryMessageArgs): string {
return `${sender} is interested in your Embed ${postTitle}. They sent you a message: ${customMessage}`;
}
}
Once you've created your custom message builder, you can register it with Skill Exchange using the extension point.
Customizing Slack Notifications
Slack notifications appear directly within your Slack workspace and can be customized to match your organization's terminology and communication style.
Prerequisites
Before customizing Slack notifications, you must first enable Slack integration. Please refer to the Slack Notifications setup section for detailed configuration instructions.
Example: Customizing Embed Notifications for Slack
The following example shows how to customize embeds notification messages. Since we're only providing a custom embeds message builder, the default message builders for mentors and hacks will continue to be used. For detailed information on available methods and customization options, refer to the EmbedsMessageBuilder, MentorsMessageBuilder, and HacksMessageBuilder documentation.
For message formatting, visit Slack's documentation for more information.
import { DefaultSlackEmbedsMessageBuilder } from '@spotify/backstage-plugin-skill-exchange-backend';
import { InquiryMessageArgs } from '@spotify/backstage-plugin-skill-exchange-node/alpha';
export class CustomSlackEmbedsMessageBuilder extends DefaultSlackEmbedsMessageBuilder {
// Override other methods as needed
buildInquiryMessage({
postUrl,
postTitle,
sender,
customMessage,
}: InquiryMessageArgs): string {
return `
:wave: <@${sender}> is interested in your Embed *<${postUrl}|${postTitle}>*.
They sent you a message:
> ${customMessage}
:rocket: *Ready to collaborate?* Reply to this message to start the conversation!
`;
}
}
Once you've created your custom message builder, you can register it with Skill Exchange using the extension point.
Registering Custom Message Builders
Once you've created your custom message builders, register them with Skill Exchange by using the skillExchangeMessageBuilderExtensionPoint
extension point.
You can register builders for both Slack and Backstage Notifications in the same module.
import { createBackendModule } from '@backstage/backend-plugin-api';
import { skillExchangeMessageBuilderExtensionPoint } from '@spotify/backstage-plugin-skill-exchange-node/alpha';
import { CustomSlackEmbedsMessageBuilder } from './customSlackEmbedsMessageBuilder';
import { CustomNotificationEmbedsMessageBuilder } from './customNotificationEmbedsMessageBuilder';
export default createBackendModule({
pluginId: 'skill-exchange',
moduleId: 'custom-message-builder',
register(env) {
env.registerInit({
deps: {
messageBuilder: skillExchangeMessageBuilderExtensionPoint,
},
async init({ messageBuilder }) {
// Register custom embeds message builder for Slack
messageBuilder.setSlackEmbedsMessageBuilder(
new CustomEmbedsMessageBuilder(),
);
// Register custom embeds message builder for Backstage Notifications
messageBuilder.setNotificationEmbedsMessageBuilder(
new CustomNotificationEmbedsMessageBuilder(),
);
// You can also register custom builders for other features
// messageBuilder.setSlackMentorsMessageBuilder(new CustomMentorsMessageBuilder());
// messageBuilder.setSlackHacksMessageBuilder(new CustomHacksMessageBuilder());
// messageBuilder.setNotificationMentorsMessageBuilder(new CustomNotificationMentorsMessageBuilder());
// messageBuilder.setNotificationHacksMessageBuilder(new CustomNotificationHacksMessageBuilder());
},
});
},
});
import { createBackend } from '@backstage/backend-defaults';
const backend = createBackend();
// ...
backend.add(import('@backstage/plugin-notifications-backend'));
backend.add(import('@spotify/backstage-plugin-skill-exchange-backend'));
backend.add(
import('@spotify/backstage-plugin-search-backend-module-skill-exchange'),
);
backend.add(import('./customSkillExchangeMessageBuilderModule'));
// ...
backend.start();