How to start with Cyborg
Warning
Saving a syntactically wrong YAML file will cause the dev server to fail.
Remember to regularly check for this and restart when needed.
How to add
new component
to a page?
// apps/jobportal/src/ui/Homepage/WorkshopTest.tsx
import { Section } from '@almacareer/cyborg-design-system/components/Section';
export default function WorkshopTest() {
return <Section>Hello Cyborg!</Section>;
}
// apps/jobportal/src/app/[locale]/page.tsx
import { Container } from '@almacareer/cyborg-design-system/components/Container';
// ...
import WorkshopTest from '@/ui/Homepage/WorkshopTest';
export default async function HomePage() {
const language = getLocale();
const { t } = await getTranslator(language);
return (
<>
<SearchContainer hasBackground>
<Heading
dangerouslySetInnerHTML={{ __html: t('page.homepage.content.h1') }}
elementType="h1"
/>
</SearchContainer>
<WorkshopTest />
<Section>
<Container variant="cygnus">
<SectionElite />
</Container>
</Section>
<Section>
<Container variant="cygnus">
<SectionAdvice />
</Container>
</Section>
</>
);
}
How to check
if featureFlag
is enabled?
# apps/jobportal/configuration/defaults/defaultFeatureFlags.yaml
apiVersion: cyborg/v1
kind: FeatureFlags
metadata:
name: default.featureFlags
spec:
applicationForm.page: false
foobar: true
// apps/jobportal/src/ui/Homepage/WorkshopTest.tsx
import { Section } from '@almacareer/cyborg-design-system/components/Section';
import { WithServerFeature } from '@almacareer/cyborg-service-container/component/server';
import container from '@generated/container.server';
export default function WorkshopTest() {
const isEnabled = container.isFeatureFlagEnabled('foobar');
return (
<Section>
<p>Hello Cyborg!</p>
<p>
Feature flag <code>foobar</code>
is {isEnabled ? 'enabled' : 'disabled'}
</p>
<WithServerFeature
name="applicationForm.page"
fallback={<strong>DISABLED</strong>}
>
ENABLED
</WithServerFeature>
</Section>
);
}
How to query value
of a parameter?
// apps/jobportal/src/ui/Homepage/WorkshopTest.tsx
import { Section } from '@almacareer/cyborg-design-system/components/Section';
import { WithServerFeature } from '@almacareer/cyborg-service-container/component/server';
import container from '@generated/container.server';
export default function WorkshopTest() {
const isEnabled = container.isFeatureFlagEnabled('foobar');
return (
<Section>
<p>Hello Cyborg!</p>
<p>
The current default language for this jobboard is{' '}
<strong>{container.getParameter('language')}</strong>
</p>
<p>
Feature flag <code>foobar</code>
is {isEnabled ? 'enabled' : 'disabled'}
</p>
<WithServerFeature
name="applicationForm.page"
fallback={<strong>DISABLED</strong>}
>
ENABLED
</WithServerFeature>
</Section>
);
}
How to override values for specific jobboards?
- Locate the configuration folder for overrides:
- apps/jobportal/configuration/{JOBBOARD_NAME}
- Find or create configuration file of a required kind
- Add of change the required option
How to
create a plugin?
mkdir plugins/my-awesome-plugin
cd plugins/my-awesome-plugin
mkdir configuration
mkdir src
Step 1: Create folder and structure
{
"name": "@almacareer/cyborg-my-awesome-plugin",
"version": "0.1.0",
"private": true,
"type": "module",
"types": "./src/index.ts",
"scripts": {
"create-registry": "tsx ../../libs/create-container/bin/run.ts -o var -c configuration --registry-only",
"lint": "npm-run-all --serial types lint:scripts",
"types": "yarn create-registry && tsc",
"test": "yarn create-registry && vitest run"
},
"dependencies": {
"@almacareer/cyborg-configuration": "workspace:^",
"@almacareer/cyborg-service-container": "workspace:^",
"@lmc-eu/spirit-web-react": "^2.4.0"
},
"devDependencies": {
"eslint-config-cyborg": "workspace:^",
"tsx": "^4.19.2",
"typescript": "^5.6.3",
"vite-tsconfig-paths": "^5.0.1",
"vitest": "~2.1.6",
"vitest-config-cyborg": "workspace:^"
},
"exports": {
".": "./src/index.ts",
"./server": "./src/server.ts"
}
}
Step 2: package.json
{
"extends": "../../configs/typescript-config-cyborg/dom",
"include": ["./src/**/*", "./tests/**/*", "./var/**/*"]
}
Step 3: tsconfig.json
import tsconfigPaths from 'vite-tsconfig-paths';
import config from 'vitest-config-cyborg';
import { mergeConfig } from 'vitest/config';
export default mergeConfig(config, {
plugins: [tsconfigPaths()],
});
Step 4: vitest.config.ts
yarn workspace @almacareer/cyborg-jobportal add @almacareer/cyborg-my-awesome-plugin
yarn install
Step 5: Add as a dependency to the main app
yarn dev
Step 6: Restart dev server
How to
create component inside a plugin?
// plugins/my-awesome-plugin/src/ui/PluginTest.tsx
export default function PluginTest() {
return <p>This is My Awesome Plugin</p>;
}
Create a component
// plugins/my-awesome-plugin/src/index.ts
import PluginTest from './ui/PluginTest';
export { PluginTest };
Export the component from plugin
// apps/jobportal/src/ui/Homepage/WorkshopTest.tsx
// ...
import { PluginTest } from '@almacareer/cyborg-my-awesome-plugin';
import {
WithServerFeature,
WithServerPlugin,
} from '@almacareer/cyborg-service-container/component/server';
export default function WorkshopTest() {
const isEnabled = container.isFeatureFlagEnabled('foobar');
const isPluginEnabled = container.isPluginEnabled('myAwesomePlugin');
return (
<Section>
<Container variant="cygnus">
{/* ... */}
{isPluginEnabled
? <PluginTest />
: <strong>My Awesome Plugin is disabled</strong>
}
<WithServerPlugin name="myAwesomePlugin">
<PluginTest />
</WithServerPlugin>
</Container>
</Section>
);
}
Use it in application
How to allow component to be overidden?
// plugins/my-awesome-plugin/package.json
{
"name": "@almacareer/cyborg-my-awesome-plugin",
"version": "0.1.0",
"private": true,
"type": "module",
"exports": {
".": "./src/index.ts",
"./server": "./src/server.ts",
"./PluginTest": "./src/ui/PluginTest.tsx"
},
"scripts": {
// ...
}
}
Allow the source file to imported
# plugins/my-awesome-plugin/configuration/components.yaml
apiVersion: cyborg/v1
kind: Components
metadata:
name: myAwesomePlugin.components
namespace: myAwesomePlugin
labels:
cyborg/plugin: myAwesomePlugin
spec:
server:
AwesomeCyborg: '@almacareer/cyborg-my-awesome-plugin/PluginTest'
Register the component in a container
// apps/jobportal/src/ui/Homepage/WorkshopTest.tsx
import { Container } from '@almacareer/cyborg-design-system/components/Container';
import { Section } from '@almacareer/cyborg-design-system/components/Section';
import {
WithServerFeature,
WithServerPlugin,
} from '@almacareer/cyborg-service-container/component/server';
import container from '@generated/container.server';
export default function WorkshopTest() {
const isEnabled = container.isFeatureFlagEnabled('foobar');
const isPluginEnabled = container.isPluginEnabled('myAwesomePlugin');
const PluginTest = container.getComponent('myAwesomePlugin.AwesomeCyborg');
return (
<Section>
<Container variant="cygnus">
<p>Hello Cyborg!</p>
{/* ... */}
{isPluginEnabled ? <PluginTest /> : <strong>My Awesome Plugin is disabled</strong>}
<WithServerPlugin name="myAwesomePlugin">
<PluginTest />
</WithServerPlugin>
</Container>
</Section>
);
}
Use it in application
// apps/jobportal/src/ui/Homepage/EvenMoreAwesomeCyborg.tsx
export default function EvenMoreAwesomeCyborg() {
return <h1>This is even more awesome!</h1>;
}
Create an override
# apps/jobportal/configuration/cyborg/myAwesomePlugin.yaml
apiVersion: cyborg/v1
kind: Components
metadata:
name: cyborg.myAwesomePlugin.Components
namespace: myAwesomePlugin
spec:
server:
AwesomeCyborg: '@/ui/Homepage/EvenMoreAwesomeCyborg'
Register the override in configuration
How to
ask for a thing
from container
inside a plugin?
# plugins/my-awesome-plugin/configuration/dependencies.yaml
apiVersion: cyborg/v1
kind: Dependencies
metadata:
name: myAwesomePlugin.Dependencies
spec:
parameters:
language: string
Declare what you expect
cd plugins/my-awesome-plugin
yarn create-registry
Generate registry (for TypeScript support)
// plugins/my-awesome-plugin/src/ui/PluginTest.tsx
import container from '@almacareer/cyborg-service-container/server';
export default function PluginTest() {
return (
<>
<p>This is My Awesome Plugin</p>
<p>
The name of the portal is {container.getBrand()}{' '}
and the default language is {container.getParameter('language')}
</p>
</>
);
}
Import container
How to
create a new route?
// plugins/my-awesome-plugin/src/pages/AwesomeHelloPage.tsx
export default function AwesomeHelloPage() {
return (
<>
<h1>This page is defined inside a plugin</h1>
</>
);
}
Create a page component
// plugins/my-awesome-plugin/src/index.ts
import AwesomeHelloPage from './pages/AwesomeHelloPage';
export { AwesomeHelloPage };
Export it from a plugin (or register ina container)
// apps/jobportal/src/app/[locale]/hello/page.tsx
import { AwesomeHelloPage } from '@almacareer/cyborg-my-awesome-plugin';
export default function HelloPage() {
return <AwesomeHelloPage />;
}
Create a Next.js route
# plugins/my-awesome-plugin/configuration/routes.yaml
apiVersion: cyborg/v1
kind: Routes
metadata:
name: myAwesomePlugin.routes
namespace: myAwesomePlugin
labels:
cyborg/plugin: myAwesomePlugin
spec:
awesomeHello:
targetPath: /hello
path:
en: /hello-en
sk: /hello-sk
cs: /hello-cs
de: /hello-de
hr: /hello-hr
Register a Cyborg route
Visit a new page

http://localhost:3000/hello-en

How to start with Cyborg
By Milan Herda
How to start with Cyborg
- 70