diff --git a/frontend/src/component/onboarding/ConnectSDKDialog.tsx b/frontend/src/component/onboarding/ConnectSDKDialog.tsx
new file mode 100644
index 0000000000..eaad1c0e9d
--- /dev/null
+++ b/frontend/src/component/onboarding/ConnectSDKDialog.tsx
@@ -0,0 +1,234 @@
+import {
+ Box,
+ Button,
+ Dialog,
+ styled,
+ type Theme,
+ Typography,
+} from '@mui/material';
+import { SingleSelectConfigButton } from '../common/DialogFormTemplate/ConfigButtons/SingleSelectConfigButton';
+import EnvironmentsIcon from '@mui/icons-material/CloudCircle';
+import { useEffect, useState } from 'react';
+import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon';
+import CodeIcon from '@mui/icons-material/Code';
+
+interface IConnectSDKDialogProps {
+ open: boolean;
+ onClose: () => void;
+ project: string;
+ environments: string[];
+}
+
+const ConceptsDefinitions = styled('div')(({ theme }) => ({
+ backgroundColor: theme.palette.background.sidebar,
+ padding: theme.spacing(8),
+ flexBasis: '30%',
+}));
+
+const IconStyle = ({ theme }: { theme: Theme }) => ({
+ color: theme.palette.primary.contrastText,
+ fontSize: theme.fontSizes.smallBody,
+ marginTop: theme.spacing(0.5),
+});
+
+const StyledProjectIcon = styled(ProjectIcon)(IconStyle);
+const StyledEnvironmentsIcon = styled(EnvironmentsIcon)(IconStyle);
+const StyledCodeIcon = styled(CodeIcon)(IconStyle);
+
+const ConceptItem = styled('div')(({ theme }) => ({
+ display: 'flex',
+ gap: theme.spacing(1.5),
+ alignItems: 'flex-start',
+ marginTop: theme.spacing(3),
+}));
+
+const ConceptSummary = styled('div')(({ theme }) => ({
+ color: theme.palette.primary.contrastText,
+ fontSize: theme.fontSizes.smallBody,
+ fontWeight: theme.fontWeight.bold,
+ marginBottom: theme.spacing(2),
+}));
+
+const ConceptDetails = styled('p')(({ theme }) => ({
+ color: theme.palette.primary.contrastText,
+ fontSize: theme.fontSizes.smallerBody,
+ marginBottom: theme.spacing(2),
+}));
+
+export const APIKeyGeneration = styled('div')(({ theme }) => ({
+ backgroundColor: theme.palette.background.paper,
+ display: 'flex',
+ flexDirection: 'column',
+ flexBasis: '70%',
+}));
+
+export const SpacedContainer = styled('div')(({ theme }) => ({
+ padding: theme.spacing(5, 8, 3, 8),
+ display: 'flex',
+ flexDirection: 'column',
+ gap: theme.spacing(3),
+}));
+
+const StyledDialog = styled(Dialog)(({ theme }) => ({
+ '& .MuiDialog-paper': {
+ borderRadius: theme.shape.borderRadiusLarge,
+ maxWidth: theme.spacing(170),
+ width: '100%',
+ backgroundColor: 'transparent',
+ },
+ padding: 0,
+ '& .MuiPaper-root > section': {
+ overflowX: 'hidden',
+ },
+}));
+
+const SectionHeader = styled('div')(({ theme }) => ({
+ fontWeight: theme.fontWeight.bold,
+ marginBottom: theme.spacing(1),
+ fontSize: theme.fontSizes.bodySize,
+}));
+
+const SectionDescription = styled('p')(({ theme }) => ({
+ color: theme.palette.text.secondary,
+ fontSize: theme.fontSizes.smallBody,
+ marginBottom: theme.spacing(2),
+}));
+
+const NextStepSection = styled('div')(({ theme }) => ({
+ marginTop: 'auto',
+ borderTop: `1px solid ${theme.palette.divider}}`,
+}));
+
+const NextStepSectionSpacedContainer = styled('div')(({ theme }) => ({
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ padding: theme.spacing(3, 8, 3, 8),
+}));
+
+export const ConnectSDKDialog = ({
+ open,
+ onClose,
+ environments,
+}: IConnectSDKDialogProps) => {
+ const [environment, setEnvironment] = useState('');
+ const longestEnv = Math.max(
+ ...environments.map((environment) => environment.length),
+ );
+
+ useEffect(() => {
+ if (environments.length > 0) {
+ setEnvironment(environments[0]);
+ }
+ }, [JSON.stringify(environments)]);
+
+ return (
+
+
+
+
+
+ Connect an SDK to Unleash
+
+
+ Environment
+
+ The environment SDK will connect to in order to
+ retrieve configuration.
+
+ {environments.length > 0 ? (
+ ({
+ label: environment,
+ value: environment,
+ }),
+ )}
+ onChange={(value: any) => {
+ setEnvironment(value);
+ }}
+ button={{
+ label: environment,
+ icon: ,
+ labelWidth: `${longestEnv + 5}ch`,
+ }}
+ search={{
+ label: 'Filter project mode options',
+ placeholder: 'Select project mode',
+ }}
+ />
+ ) : null}
+
+
+
+ API Key
+
+ You currently have no active API keys for this
+ project/environment combination. You'll need to
+ generate and API key in order to proceed with
+ connecting your SDK.
+
+
+
+
+
+
+
+
+ Next: Choose SDK and connect
+
+
+
+
+
+
+
+
+
+
+ Flags live in projects
+
+
+ Projects are containers for feature flags. When
+ you create a feature flag it will belong to the
+ project you create it in.
+
+
+
+
+
+
+
+ Flags have configuration in environments
+
+
+ In Unleash you can have multiple environments.
+ Each feature flag will have different
+ configuration in every environment.
+
+
+
+
+
+
+
+ SDKs connect to Unleash to retrieve
+ configuration
+
+
+ When you connect an SDK to Unleash it will use
+ the API key to deduce which feature flags to
+ retrieve and from which environment to retrieve
+ configuration.
+
+
+
+
+
+
+ );
+};
diff --git a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx b/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx
index 359c2ea06b..183d150412 100644
--- a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx
+++ b/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx
@@ -42,6 +42,7 @@ import { AvatarCell } from './AvatarCell';
import { ProjectOnboarding } from './ProjectOnboarding/ProjectOnboarding';
import { useUiFlag } from 'hooks/useUiFlag';
import { styled } from '@mui/material';
+import { ConnectSDKDialog } from '../../../onboarding/ConnectSDKDialog';
interface IPaginatedProjectFeatureTogglesProps {
environments: string[];
@@ -489,6 +490,13 @@ export const ProjectFeatureToggles = ({
{rowActionsDialogs}
{featureToggleModals}
+
+ {}}
+ project={projectId}
+ environments={environments}
+ />