diff --git a/e2e-chatbot-app-next/.env.example b/e2e-chatbot-app-next/.env.example
index 7dad22c9..7d25e3f9 100644
--- a/e2e-chatbot-app-next/.env.example
+++ b/e2e-chatbot-app-next/.env.example
@@ -60,3 +60,10 @@ DATABRICKS_SERVING_ENDPOINT=your-serving-endpoint
# In production (Databricks Apps), this is injected automatically when the
# experiment resource is configured in databricks.yml + app.yaml.
# MLFLOW_EXPERIMENT_ID=/Users/your-email@company.com/chatbot-feedback-dev
+
+# ============================================
+# UI Configuration (Optional)
+# ============================================
+# Greeting / empty-state message shown in the chat UI before the first message.
+# Defaults to "What would you like to know?" when unset.
+# CHAT_GREETING=How can I help with your account today?
diff --git a/e2e-chatbot-app-next/client/src/components/greeting.tsx b/e2e-chatbot-app-next/client/src/components/greeting.tsx
index c1213bc0..d24f8c8a 100644
--- a/e2e-chatbot-app-next/client/src/components/greeting.tsx
+++ b/e2e-chatbot-app-next/client/src/components/greeting.tsx
@@ -1,6 +1,8 @@
import { motion } from 'framer-motion';
+import { useAppConfig } from '@/contexts/AppConfigContext';
export const Greeting = () => {
+ const { greeting } = useAppConfig();
return (
{
exit={{ opacity: 0, y: 10 }}
className="font-semibold text-lg md:text-xl text-center"
>
- What would you like to know?
+ {greeting}
);
diff --git a/e2e-chatbot-app-next/client/src/contexts/AppConfigContext.tsx b/e2e-chatbot-app-next/client/src/contexts/AppConfigContext.tsx
index 00b818d4..a1a211df 100644
--- a/e2e-chatbot-app-next/client/src/contexts/AppConfigContext.tsx
+++ b/e2e-chatbot-app-next/client/src/contexts/AppConfigContext.tsx
@@ -2,11 +2,14 @@ import { createContext, useContext, type ReactNode } from 'react';
import useSWR from 'swr';
import { fetcher } from '@/lib/utils';
+export const DEFAULT_GREETING = 'What would you like to know?';
+
interface ConfigResponse {
features: {
chatHistory: boolean;
feedback: boolean;
};
+ greeting?: string;
obo?: {
missingScopes: string[];
};
@@ -18,6 +21,7 @@ interface AppConfigContextType {
error: Error | undefined;
chatHistoryEnabled: boolean;
feedbackEnabled: boolean;
+ greeting: string;
oboMissingScopes: string[];
}
@@ -44,6 +48,7 @@ export function AppConfigProvider({ children }: { children: ReactNode }) {
// Default to true until loaded to avoid breaking existing behavior
chatHistoryEnabled: data?.features.chatHistory ?? true,
feedbackEnabled: data?.features.feedback ?? false,
+ greeting: data?.greeting ?? DEFAULT_GREETING,
oboMissingScopes: data?.obo?.missingScopes ?? [],
};
diff --git a/e2e-chatbot-app-next/server/src/routes/config.ts b/e2e-chatbot-app-next/server/src/routes/config.ts
index 02c2279a..4d439e03 100644
--- a/e2e-chatbot-app-next/server/src/routes/config.ts
+++ b/e2e-chatbot-app-next/server/src/routes/config.ts
@@ -28,7 +28,9 @@ function getScopesFromToken(token: string): string[] {
/**
* GET /api/config - Get application configuration
- * Returns feature flags and OBO status based on environment configuration.
+ * Returns feature flags, the empty-state greeting, and OBO status based on
+ * environment configuration. The greeting comes from CHAT_GREETING (the client
+ * falls back to a default when unset).
* If the user's OBO token is present, decodes it to check which required
* scopes are missing — the banner only shows missing scopes.
*/
@@ -54,6 +56,7 @@ configRouter.get('/', async (req: Request, res: Response) => {
chatHistory: isDatabaseAvailable(),
feedback: !!process.env.MLFLOW_EXPERIMENT_ID,
},
+ greeting: process.env.CHAT_GREETING || undefined,
obo: {
missingScopes,
},
diff --git a/e2e-chatbot-app-next/tests/routes/config.test.ts b/e2e-chatbot-app-next/tests/routes/config.test.ts
index 9a354205..2cb2ea08 100644
--- a/e2e-chatbot-app-next/tests/routes/config.test.ts
+++ b/e2e-chatbot-app-next/tests/routes/config.test.ts
@@ -46,6 +46,17 @@ test.describe('/api/config', () => {
expect(data1).toEqual(data2);
});
+ test('GET /api/config omits greeting when CHAT_GREETING is unset', async ({
+ adaContext,
+ }) => {
+ // CHAT_GREETING is not set in the test environment, so the server omits the
+ // field and the client falls back to its default greeting.
+ const response = await adaContext.request.get('/api/config');
+ const data = await response.json();
+
+ expect(data.greeting).toBeUndefined();
+ });
+
test('GET /api/config returns OBO info', async ({
adaContext,
}) => {