diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 7224f2e9c03ddd53e146dcc8d61ceb955b823ff3..8007b5ad1304cca10313278167b557e025489ccf 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -120,6 +120,7 @@ export default function App() {
 
               {/* Onboarding Flow */}
               <Route path="/onboarding" element={<OnboardingFlow />} />
+              <Route path="/onboarding/:step" element={<OnboardingFlow />} />
             </Routes>
             <ToastContainer />
           </PfpProvider>
diff --git a/frontend/src/components/EmbeddingSelection/AzureAiOptions/index.jsx b/frontend/src/components/EmbeddingSelection/AzureAiOptions/index.jsx
index e7767900aec6e90124fa660fb1090a25632bd2ec..c782c51f334c48595e89408aa32923480b9fbfbe 100644
--- a/frontend/src/components/EmbeddingSelection/AzureAiOptions/index.jsx
+++ b/frontend/src/components/EmbeddingSelection/AzureAiOptions/index.jsx
@@ -1,53 +1,55 @@
 export default function AzureAiOptions({ settings }) {
   return (
-    <>
-      <div className="flex flex-col w-60">
-        <label className="text-white text-sm font-semibold block mb-4">
-          Azure Service Endpoint
-        </label>
-        <input
-          type="url"
-          name="AzureOpenAiEndpoint"
-          className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-          placeholder="https://my-azure.openai.azure.com"
-          defaultValue={settings?.AzureOpenAiEndpoint}
-          required={true}
-          autoComplete="off"
-          spellCheck={false}
-        />
-      </div>
+    <div className="w-full flex flex-col gap-y-4">
+      <div className="w-full flex items-center gap-4">
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            Azure Service Endpoint
+          </label>
+          <input
+            type="url"
+            name="AzureOpenAiEndpoint"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="https://my-azure.openai.azure.com"
+            defaultValue={settings?.AzureOpenAiEndpoint}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
 
-      <div className="flex flex-col w-60">
-        <label className="text-white text-sm font-semibold block mb-4">
-          API Key
-        </label>
-        <input
-          type="password"
-          name="AzureOpenAiKey"
-          className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-          placeholder="Azure OpenAI API Key"
-          defaultValue={settings?.AzureOpenAiKey ? "*".repeat(20) : ""}
-          required={true}
-          autoComplete="off"
-          spellCheck={false}
-        />
-      </div>
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            API Key
+          </label>
+          <input
+            type="password"
+            name="AzureOpenAiKey"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="Azure OpenAI API Key"
+            defaultValue={settings?.AzureOpenAiKey ? "*".repeat(20) : ""}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
 
-      <div className="flex flex-col w-60">
-        <label className="text-white text-sm font-semibold block mb-4">
-          Embedding Deployment Name
-        </label>
-        <input
-          type="text"
-          name="AzureOpenAiEmbeddingModelPref"
-          className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-          placeholder="Azure OpenAI embedding model deployment name"
-          defaultValue={settings?.AzureOpenAiEmbeddingModelPref}
-          required={true}
-          autoComplete="off"
-          spellCheck={false}
-        />
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            Embedding Deployment Name
+          </label>
+          <input
+            type="text"
+            name="AzureOpenAiEmbeddingModelPref"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="Azure OpenAI embedding model deployment name"
+            defaultValue={settings?.AzureOpenAiEmbeddingModelPref}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
       </div>
-    </>
+    </div>
   );
 }
diff --git a/frontend/src/components/EmbeddingSelection/LocalAiOptions/index.jsx b/frontend/src/components/EmbeddingSelection/LocalAiOptions/index.jsx
index 2b976e1428b2ea995f527843e16bf8a00129f8ab..6f81712c14bd2578b95e651fb0b05ee4cc7f8d55 100644
--- a/frontend/src/components/EmbeddingSelection/LocalAiOptions/index.jsx
+++ b/frontend/src/components/EmbeddingSelection/LocalAiOptions/index.jsx
@@ -10,72 +10,72 @@ export default function LocalAiOptions({ settings }) {
   const [apiKey, setApiKey] = useState(settings?.LocalAiApiKey);
 
   return (
-    <>
+    <div className="w-full flex flex-col gap-y-4">
       <div className="w-full flex items-center gap-4">
-        <div className="flex flex-col w-60">
-          <label className="text-white text-sm font-semibold block mb-4">
-            LocalAI Base URL
-          </label>
-          <input
-            type="url"
-            name="EmbeddingBasePath"
-            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-            placeholder="http://localhost:8080/v1"
-            defaultValue={settings?.EmbeddingBasePath}
-            onChange={(e) => setBasePathValue(e.target.value)}
-            onBlur={() => setBasePath(basePathValue)}
-            required={true}
-            autoComplete="off"
-            spellCheck={false}
-          />
-        </div>
-        <LocalAIModelSelection
-          settings={settings}
-          apiKey={apiKey}
-          basePath={basePath}
-        />
-        <div className="flex flex-col w-60">
-          <label className="text-white text-sm font-semibold block mb-4">
-            Max embedding chunk length
-          </label>
-          <input
-            type="number"
-            name="EmbeddingModelMaxChunkLength"
-            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-            placeholder="1000"
-            min={1}
-            onScroll={(e) => e.target.blur()}
-            defaultValue={settings?.EmbeddingModelMaxChunkLength}
-            required={false}
-            autoComplete="off"
+        <div className="w-full flex items-center gap-4">
+          <div className="flex flex-col w-60">
+            <label className="text-white text-sm font-semibold block mb-4">
+              LocalAI Base URL
+            </label>
+            <input
+              type="url"
+              name="EmbeddingBasePath"
+              className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+              placeholder="http://localhost:8080/v1"
+              defaultValue={settings?.EmbeddingBasePath}
+              onChange={(e) => setBasePathValue(e.target.value)}
+              onBlur={() => setBasePath(basePathValue)}
+              required={true}
+              autoComplete="off"
+              spellCheck={false}
+            />
+          </div>
+          <LocalAIModelSelection
+            settings={settings}
+            apiKey={apiKey}
+            basePath={basePath}
           />
-        </div>
-      </div>
-      <div className="w-full flex items-center gap-4">
-        <div className="flex flex-col w-60">
-          <div className="flex flex-col gap-y-1 mb-4">
-            <label className="text-white text-sm font-semibold block">
-              Local AI API Key
+          <div className="flex flex-col w-60">
+            <label className="text-white text-sm font-semibold block mb-4">
+              Max embedding chunk length
             </label>
-            <p className="text-xs italic text-white/60">
-              optional API key to use if running LocalAI with API keys.
-            </p>
+            <input
+              type="number"
+              name="EmbeddingModelMaxChunkLength"
+              className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+              placeholder="1000"
+              min={1}
+              onScroll={(e) => e.target.blur()}
+              defaultValue={settings?.EmbeddingModelMaxChunkLength}
+              required={false}
+              autoComplete="off"
+            />
           </div>
+        </div>
+        <div className="w-full flex items-center gap-4">
+          <div className="flex flex-col w-60">
+            <div className="flex flex-col gap-y-1 mb-4">
+              <label className="text-white text-sm font-semibold flex items-center gap-x-2">
+                Local AI API Key{" "}
+                <p className="!text-xs !italic !font-thin">optional</p>
+              </label>
+            </div>
 
-          <input
-            type="password"
-            name="LocalAiApiKey"
-            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-            placeholder="sk-mysecretkey"
-            defaultValue={settings?.LocalAiApiKey ? "*".repeat(20) : ""}
-            autoComplete="off"
-            spellCheck={false}
-            onChange={(e) => setApiKeyValue(e.target.value)}
-            onBlur={() => setApiKey(apiKeyValue)}
-          />
+            <input
+              type="password"
+              name="LocalAiApiKey"
+              className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+              placeholder="sk-mysecretkey"
+              defaultValue={settings?.LocalAiApiKey ? "*".repeat(20) : ""}
+              autoComplete="off"
+              spellCheck={false}
+              onChange={(e) => setApiKeyValue(e.target.value)}
+              onBlur={() => setApiKey(apiKeyValue)}
+            />
+          </div>
         </div>
       </div>
-    </>
+    </div>
   );
 }
 
diff --git a/frontend/src/components/EmbeddingSelection/OpenAiOptions/index.jsx b/frontend/src/components/EmbeddingSelection/OpenAiOptions/index.jsx
index f38f7c445ee2ea0d8a63ed1eac5c3c752efbfa2b..dd00d67abdd564b9e49c0177546323e35d9d3d7d 100644
--- a/frontend/src/components/EmbeddingSelection/OpenAiOptions/index.jsx
+++ b/frontend/src/components/EmbeddingSelection/OpenAiOptions/index.jsx
@@ -1,34 +1,36 @@
 export default function OpenAiOptions({ settings }) {
   return (
-    <>
-      <div className="flex flex-col w-60">
-        <label className="text-white text-sm font-semibold block mb-4">
-          API Key
-        </label>
-        <input
-          type="password"
-          name="OpenAiKey"
-          className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-          placeholder="OpenAI API Key"
-          defaultValue={settings?.OpenAiKey ? "*".repeat(20) : ""}
-          required={true}
-          autoComplete="off"
-          spellCheck={false}
-        />
+    <div className="w-full flex flex-col gap-y-4">
+      <div className="w-full flex items-center gap-4">
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            API Key
+          </label>
+          <input
+            type="password"
+            name="OpenAiKey"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="OpenAI API Key"
+            defaultValue={settings?.OpenAiKey ? "*".repeat(20) : ""}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            Model Preference
+          </label>
+          <select
+            disabled={true}
+            className="cursor-not-allowed bg-zinc-900 border border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
+          >
+            <option disabled={true} selected={true}>
+              text-embedding-ada-002
+            </option>
+          </select>
+        </div>
       </div>
-      <div className="flex flex-col w-60">
-        <label className="text-white text-sm font-semibold block mb-4">
-          Model Preference
-        </label>
-        <select
-          disabled={true}
-          className="cursor-not-allowed bg-zinc-900 border border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
-        >
-          <option disabled={true} selected={true}>
-            text-embedding-ada-002
-          </option>
-        </select>
-      </div>
-    </>
+    </div>
   );
 }
diff --git a/frontend/src/components/LLMSelection/AzureAiOptions/index.jsx b/frontend/src/components/LLMSelection/AzureAiOptions/index.jsx
index 2978651016c9baa5d9db83ac81cbb62bed969325..ce54d3d60dea414c77446284469643c9f6c76fd5 100644
--- a/frontend/src/components/LLMSelection/AzureAiOptions/index.jsx
+++ b/frontend/src/components/LLMSelection/AzureAiOptions/index.jsx
@@ -1,87 +1,92 @@
 export default function AzureAiOptions({ settings }) {
   return (
-    <>
-      <div className="flex flex-col w-60">
-        <label className="text-white text-sm font-semibold block mb-4">
-          Azure Service Endpoint
-        </label>
-        <input
-          type="url"
-          name="AzureOpenAiEndpoint"
-          className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-          placeholder="https://my-azure.openai.azure.com"
-          defaultValue={settings?.AzureOpenAiEndpoint}
-          required={true}
-          autoComplete="off"
-          spellCheck={false}
-        />
-      </div>
+    <div className="w-full flex flex-col gap-y-4">
+      <div className="w-full flex items-center gap-4">
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            Azure Service Endpoint
+          </label>
+          <input
+            type="url"
+            name="AzureOpenAiEndpoint"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="https://my-azure.openai.azure.com"
+            defaultValue={settings?.AzureOpenAiEndpoint}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
 
-      <div className="flex flex-col w-60">
-        <label className="text-white text-sm font-semibold block mb-4">
-          API Key
-        </label>
-        <input
-          type="password"
-          name="AzureOpenAiKey"
-          className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-          placeholder="Azure OpenAI API Key"
-          defaultValue={settings?.AzureOpenAiKey ? "*".repeat(20) : ""}
-          required={true}
-          autoComplete="off"
-          spellCheck={false}
-        />
-      </div>
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            API Key
+          </label>
+          <input
+            type="password"
+            name="AzureOpenAiKey"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="Azure OpenAI API Key"
+            defaultValue={settings?.AzureOpenAiKey ? "*".repeat(20) : ""}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
 
-      <div className="flex flex-col w-60">
-        <label className="text-white text-sm font-semibold block mb-4">
-          Chat Deployment Name
-        </label>
-        <input
-          type="text"
-          name="AzureOpenAiModelPref"
-          className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-          placeholder="Azure OpenAI chat model deployment name"
-          defaultValue={settings?.AzureOpenAiModelPref}
-          required={true}
-          autoComplete="off"
-          spellCheck={false}
-        />
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            Chat Deployment Name
+          </label>
+          <input
+            type="text"
+            name="AzureOpenAiModelPref"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="Azure OpenAI chat model deployment name"
+            defaultValue={settings?.AzureOpenAiModelPref}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
       </div>
 
-      <div className="flex flex-col w-60">
-        <label className="text-white text-sm font-semibold block mb-4">
-          Chat Model Token Limit
-        </label>
-        <select
-          name="AzureOpenAiTokenLimit"
-          defaultValue={settings?.AzureOpenAiTokenLimit || 4096}
-          className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-          required={true}
-        >
-          <option value={4096}>4,096 (gpt-3.5-turbo)</option>
-          <option value={16384}>16,384 (gpt-3.5-16k)</option>
-          <option value={8192}>8,192 (gpt-4)</option>
-          <option value={32768}>32,768 (gpt-4-32k)</option>
-          <option value={128000}>128,000 (gpt-4-turbo)</option>
-        </select>
-      </div>
+      <div className="w-full flex items-center gap-4">
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            Chat Model Token Limit
+          </label>
+          <select
+            name="AzureOpenAiTokenLimit"
+            defaultValue={settings?.AzureOpenAiTokenLimit || 4096}
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            required={true}
+          >
+            <option value={4096}>4,096 (gpt-3.5-turbo)</option>
+            <option value={16384}>16,384 (gpt-3.5-16k)</option>
+            <option value={8192}>8,192 (gpt-4)</option>
+            <option value={32768}>32,768 (gpt-4-32k)</option>
+            <option value={128000}>128,000 (gpt-4-turbo)</option>
+          </select>
+        </div>
 
-      <div className="flex flex-col w-60">
-        <label className="text-white text-sm font-semibold block mb-4">
-          Embedding Deployment Name
-        </label>
-        <input
-          type="text"
-          name="AzureOpenAiEmbeddingModelPref"
-          className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-          placeholder="Azure OpenAI embedding model deployment name"
-          defaultValue={settings?.AzureOpenAiEmbeddingModelPref}
-          required={true}
-          autoComplete="off"
-          spellCheck={false}
-        />
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            Embedding Deployment Name
+          </label>
+          <input
+            type="text"
+            name="AzureOpenAiEmbeddingModelPref"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="Azure OpenAI embedding model deployment name"
+            defaultValue={settings?.AzureOpenAiEmbeddingModelPref}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
+        <div className="flex-flex-col w-60"></div>
       </div>
-    </>
+    </div>
   );
 }
diff --git a/frontend/src/components/LLMSelection/OpenAiOptions/index.jsx b/frontend/src/components/LLMSelection/OpenAiOptions/index.jsx
index fd2f876651b505f647966f5c2331166a1734ac84..cbd83edb99aa85b5934d5d55e0229d5ad4c5824f 100644
--- a/frontend/src/components/LLMSelection/OpenAiOptions/index.jsx
+++ b/frontend/src/components/LLMSelection/OpenAiOptions/index.jsx
@@ -6,7 +6,7 @@ export default function OpenAiOptions({ settings }) {
   const [openAIKey, setOpenAIKey] = useState(settings?.OpenAiKey);
 
   return (
-    <>
+    <div className="flex gap-x-4">
       <div className="flex flex-col w-60">
         <label className="text-white text-sm font-semibold block mb-4">
           API Key
@@ -25,7 +25,7 @@ export default function OpenAiOptions({ settings }) {
         />
       </div>
       <OpenAIModelSelection settings={settings} apiKey={openAIKey} />
-    </>
+    </div>
   );
 }
 
@@ -87,7 +87,7 @@ function OpenAIModelSelection({ apiKey, settings }) {
                 <option
                   key={model}
                   value={model}
-                  selected={settings.OpenAiModelPref === model}
+                  selected={settings?.OpenAiModelPref === model}
                 >
                   {model}
                 </option>
@@ -102,7 +102,7 @@ function OpenAIModelSelection({ apiKey, settings }) {
                 <option
                   key={model.id}
                   value={model.id}
-                  selected={settings.OpenAiModelPref === model.id}
+                  selected={settings?.OpenAiModelPref === model.id}
                 >
                   {model.id}
                 </option>
diff --git a/frontend/src/components/PrivateRoute/index.jsx b/frontend/src/components/PrivateRoute/index.jsx
index 4640646321c87bda9413c598c8cc332ec0f73436..165141bbb3a67de6333db69b614107a7803cbf24 100644
--- a/frontend/src/components/PrivateRoute/index.jsx
+++ b/frontend/src/components/PrivateRoute/index.jsx
@@ -89,7 +89,7 @@ export function AdminRoute({ Component }) {
   if (isAuthd === null) return <FullScreenLoader />;
 
   if (shouldRedirectToOnboarding) {
-    return <Navigate to={paths.onboarding()} />;
+    return <Navigate to={paths.onboarding.home()} />;
   }
 
   const user = userFromStorage();
@@ -110,7 +110,7 @@ export function ManagerRoute({ Component }) {
   if (isAuthd === null) return <FullScreenLoader />;
 
   if (shouldRedirectToOnboarding) {
-    return <Navigate to={paths.onboarding()} />;
+    return <Navigate to={paths.onboarding.home()} />;
   }
 
   const user = userFromStorage();
diff --git a/frontend/src/components/VectorDBSelection/ChromaDBOptions/index.jsx b/frontend/src/components/VectorDBSelection/ChromaDBOptions/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..ae7af68fb84772aeb924d40887f4b188630b5389
--- /dev/null
+++ b/frontend/src/components/VectorDBSelection/ChromaDBOptions/index.jsx
@@ -0,0 +1,51 @@
+export default function ChromaDBOptions({ settings }) {
+  return (
+    <div className="w-full flex flex-col gap-y-4">
+      <div className="w-full flex items-center gap-4">
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            Chroma Endpoint
+          </label>
+          <input
+            type="url"
+            name="ChromaEndpoint"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="http://localhost:8000"
+            defaultValue={settings?.ChromaEndpoint}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
+
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            API Header
+          </label>
+          <input
+            name="ChromaApiHeader"
+            autoComplete="off"
+            type="text"
+            defaultValue={settings?.ChromaApiHeader}
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="X-Api-Key"
+          />
+        </div>
+
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            API Key
+          </label>
+          <input
+            name="ChromaApiKey"
+            autoComplete="off"
+            type="password"
+            defaultValue={settings?.ChromaApiKey ? "*".repeat(20) : ""}
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="sk-myApiKeyToAccessMyChromaInstance"
+          />
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git a/frontend/src/components/VectorDBSelection/LanceDBOptions/index.jsx b/frontend/src/components/VectorDBSelection/LanceDBOptions/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..942a3666da7b78aac975a45e53fc4099b836e724
--- /dev/null
+++ b/frontend/src/components/VectorDBSelection/LanceDBOptions/index.jsx
@@ -0,0 +1,9 @@
+export default function LanceDBOptions() {
+  return (
+    <div className="w-full h-10 items-center justify-center flex">
+      <p className="text-sm font-base text-white text-opacity-60">
+        There is no configuration needed for LanceDB.
+      </p>
+    </div>
+  );
+}
diff --git a/frontend/src/components/VectorDBSelection/PineconeDBOptions/index.jsx b/frontend/src/components/VectorDBSelection/PineconeDBOptions/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..5491f758c67791a36c50568e3faed1f1ac2cb54c
--- /dev/null
+++ b/frontend/src/components/VectorDBSelection/PineconeDBOptions/index.jsx
@@ -0,0 +1,55 @@
+export default function PineconeDBOptions({ settings }) {
+  return (
+    <div className="w-full flex flex-col gap-y-4">
+      <div className="w-full flex items-center gap-4">
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            Pinecone DB API Key
+          </label>
+          <input
+            type="password"
+            name="PineConeKey"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="Pinecone API Key"
+            defaultValue={settings?.PineConeKey ? "*".repeat(20) : ""}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
+
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            Pinecone Index Environment
+          </label>
+          <input
+            type="text"
+            name="PineConeEnvironment"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="us-gcp-west-1"
+            defaultValue={settings?.PineConeEnvironment}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
+
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            Pinecone Index Name
+          </label>
+          <input
+            type="text"
+            name="PineConeIndex"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="my-index"
+            defaultValue={settings?.PineConeIndex}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git a/frontend/src/components/VectorDBSelection/QDrantDBOptions/index.jsx b/frontend/src/components/VectorDBSelection/QDrantDBOptions/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..e1e9d90f6807be87fbec9fc6ba8688bb004e8cc4
--- /dev/null
+++ b/frontend/src/components/VectorDBSelection/QDrantDBOptions/index.jsx
@@ -0,0 +1,38 @@
+export default function QDrantDBOptions({ settings }) {
+  return (
+    <div className="w-full flex flex-col gap-y-4">
+      <div className="w-full flex items-center gap-4">
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            QDrant API Endpoint
+          </label>
+          <input
+            type="url"
+            name="QdrantEndpoint"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="http://localhost:6633"
+            defaultValue={settings?.QdrantEndpoint}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
+
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            API Key
+          </label>
+          <input
+            type="password"
+            name="QdrantApiKey"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="wOeqxsYP4....1244sba"
+            defaultValue={settings?.QdrantApiKey}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git a/frontend/src/components/VectorDBSelection/WeaviateDBOptions/index.jsx b/frontend/src/components/VectorDBSelection/WeaviateDBOptions/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..5d7494ed155e831f7e21122bc350b07b78755cd6
--- /dev/null
+++ b/frontend/src/components/VectorDBSelection/WeaviateDBOptions/index.jsx
@@ -0,0 +1,38 @@
+export default function WeaviateDBOptions({ settings }) {
+  return (
+    <div className="w-full flex flex-col gap-y-4">
+      <div className="w-full flex items-center gap-4">
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            Weaviate Endpoint
+          </label>
+          <input
+            type="url"
+            name="WeaviateEndpoint"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="http://localhost:8080"
+            defaultValue={settings?.WeaviateEndpoint}
+            required={true}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
+
+        <div className="flex flex-col w-60">
+          <label className="text-white text-sm font-semibold block mb-4">
+            API Key
+          </label>
+          <input
+            type="password"
+            name="WeaviateApiKey"
+            className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
+            placeholder="sk-123Abcweaviate"
+            defaultValue={settings?.WeaviateApiKey}
+            autoComplete="off"
+            spellCheck={false}
+          />
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git a/frontend/src/media/illustrations/create-workspace.png b/frontend/src/media/illustrations/create-workspace.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e31174e5d1d7543adb75ec1ee7ec1ac6182944e
Binary files /dev/null and b/frontend/src/media/illustrations/create-workspace.png differ
diff --git a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/AppearanceSetup/index.jsx b/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/AppearanceSetup/index.jsx
deleted file mode 100644
index 30e87b0ac6b7420a9a18d455da3232369dea97a1..0000000000000000000000000000000000000000
--- a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/AppearanceSetup/index.jsx
+++ /dev/null
@@ -1,145 +0,0 @@
-import React, { memo, useEffect, useState } from "react";
-import System from "@/models/system";
-import AnythingLLM from "@/media/logo/anything-llm.png";
-import useLogo from "@/hooks/useLogo";
-import { Plus } from "@phosphor-icons/react";
-import showToast from "@/utils/toast";
-
-function AppearanceSetup({ prevStep, nextStep }) {
-  const { logo: _initLogo, setLogo: _setLogo } = useLogo();
-  const [logo, setLogo] = useState("");
-  const [isDefaultLogo, setIsDefaultLogo] = useState(true);
-
-  useEffect(() => {
-    async function logoInit() {
-      setLogo(_initLogo || "");
-      const _isDefaultLogo = await System.isDefaultLogo();
-      setIsDefaultLogo(_isDefaultLogo);
-    }
-    logoInit();
-  }, [_initLogo]);
-
-  const handleFileUpload = async (event) => {
-    const file = event.target.files[0];
-    if (!file) return false;
-
-    const objectURL = URL.createObjectURL(file);
-    setLogo(objectURL);
-
-    const formData = new FormData();
-    formData.append("logo", file);
-    const { success, error } = await System.uploadLogo(formData);
-    if (!success) {
-      showToast(`Failed to upload logo: ${error}`, "error");
-      setLogo(_initLogo);
-      return;
-    }
-
-    const logoURL = await System.fetchLogo();
-    _setLogo(logoURL);
-
-    showToast("Image uploaded successfully.", "success");
-    setIsDefaultLogo(false);
-  };
-
-  const handleRemoveLogo = async () => {
-    setLogo("");
-    setIsDefaultLogo(true);
-
-    const { success, error } = await System.removeCustomLogo();
-    if (!success) {
-      console.error("Failed to remove logo:", error);
-      showToast(`Failed to remove logo: ${error}`, "error");
-      const logoURL = await System.fetchLogo();
-      setLogo(logoURL);
-      setIsDefaultLogo(false);
-      return;
-    }
-
-    const logoURL = await System.fetchLogo();
-    _setLogo(logoURL);
-
-    showToast("Image successfully removed.", "success");
-  };
-
-  return (
-    <div className="w-full">
-      <div className="flex flex-col w-full px-8 py-4">
-        <div className="flex flex-col gap-y-2">
-          <h2 className="text-white text-sm font-medium">Custom Logo</h2>
-          <p className="text-sm font-base text-white/60">
-            Upload your custom logo to make your chatbot yours.
-          </p>
-        </div>
-        <div className="flex md:flex-row flex-col items-center">
-          <img
-            src={logo}
-            alt="Uploaded Logo"
-            className="w-48 h-48 object-contain mr-6"
-            hidden={isDefaultLogo}
-            onError={(e) => (e.target.src = AnythingLLM)}
-          />
-          <div className="flex flex-row gap-x-8">
-            <label className="mt-5 hover:opacity-60" hidden={!isDefaultLogo}>
-              <input
-                id="logo-upload"
-                type="file"
-                accept="image/*"
-                className="hidden"
-                onChange={handleFileUpload}
-              />
-              <div
-                className="w-80 py-4 bg-zinc-900/50 rounded-2xl border-2 border-dashed border-white border-opacity-60 justify-center items-center inline-flex cursor-pointer"
-                htmlFor="logo-upload"
-              >
-                <div className="flex flex-col items-center justify-center">
-                  <div className="rounded-full bg-white/40">
-                    <Plus className="w-6 h-6 text-black/80 m-2" />
-                  </div>
-                  <div className="text-white text-opacity-80 text-sm font-semibold py-1">
-                    Add a custom logo
-                  </div>
-                  <div className="text-white text-opacity-60 text-xs font-medium py-1">
-                    Recommended size: 800 x 200
-                  </div>
-                </div>
-              </div>
-            </label>
-            <button
-              onClick={handleRemoveLogo}
-              className="text-white text-base font-medium hover:text-opacity-60"
-            >
-              Delete
-            </button>
-          </div>
-        </div>
-      </div>
-      <div className="flex w-full justify-between items-center px-6 py-4 space-x-6 border-t rounded-b border-gray-500/50">
-        <button
-          onClick={prevStep}
-          type="button"
-          className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-        >
-          Back
-        </button>
-        <div className="flex gap-2">
-          <button
-            onClick={() => nextStep("user_mode_setup")}
-            type="button"
-            className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-          >
-            Skip
-          </button>
-          <button
-            onClick={() => nextStep("user_mode_setup")}
-            type="button"
-            className="border border-slate-200 px-4 py-2 rounded-lg text-slate-800 bg-slate-200 text-sm items-center flex gap-x-2 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow"
-          >
-            Continue
-          </button>
-        </div>
-      </div>
-    </div>
-  );
-}
-export default memo(AppearanceSetup);
diff --git a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/CreateFirstWorkspace/index.jsx b/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/CreateFirstWorkspace/index.jsx
deleted file mode 100644
index d2624ef6a103324a133a8d86dbf6dd28181dcca9..0000000000000000000000000000000000000000
--- a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/CreateFirstWorkspace/index.jsx
+++ /dev/null
@@ -1,68 +0,0 @@
-import React, { memo } from "react";
-import { useNavigate } from "react-router-dom";
-import paths from "@/utils/paths";
-import Workspace from "@/models/workspace";
-
-function CreateFirstWorkspace({ prevStep }) {
-  const navigate = useNavigate();
-
-  const handleCreate = async (e) => {
-    e.preventDefault();
-    const form = new FormData(e.target);
-    const { workspace, error } = await Workspace.new({
-      name: form.get("name"),
-      onboardingComplete: true,
-    });
-    if (!!workspace) {
-      navigate(paths.home());
-    } else {
-      alert(error);
-    }
-  };
-
-  return (
-    <div>
-      <form onSubmit={handleCreate} className="flex flex-col w-full">
-        <div className="flex flex-col w-full md:px-8 py-12">
-          <div className="space-y-6 flex h-full w-96">
-            <div className="w-full flex flex-col gap-y-4">
-              <div>
-                <label
-                  htmlFor="name"
-                  className="block mb-2 text-sm font-medium text-white"
-                >
-                  Workspace name
-                </label>
-                <input
-                  name="name"
-                  type="text"
-                  className="bg-zinc-900 border border-gray-500 text-white text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
-                  placeholder="My workspace"
-                  minLength={4}
-                  required={true}
-                  autoComplete="off"
-                />
-              </div>
-            </div>
-          </div>
-        </div>
-        <div className="flex w-full justify-end items-center px-6 py-4 space-x-2 border-t rounded-b border-gray-500/50">
-          <button
-            onClick={prevStep}
-            type="button"
-            className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-          >
-            Back
-          </button>
-          <button
-            type="submit"
-            className="border border-slate-200 px-4 py-2 rounded-lg text-slate-800 bg-slate-200 text-sm items-center flex gap-x-2 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow"
-          >
-            Finish
-          </button>
-        </div>
-      </form>
-    </div>
-  );
-}
-export default memo(CreateFirstWorkspace);
diff --git a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/EmbeddingSelection/index.jsx b/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/EmbeddingSelection/index.jsx
deleted file mode 100644
index 98e1262a04f8993046d8bbf712be964aabae2824..0000000000000000000000000000000000000000
--- a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/EmbeddingSelection/index.jsx
+++ /dev/null
@@ -1,136 +0,0 @@
-import React, { memo, useEffect, useState } from "react";
-import AnythingLLMIcon from "@/media/logo/anything-llm-icon.png";
-import OpenAiLogo from "@/media/llmprovider/openai.png";
-import AzureOpenAiLogo from "@/media/llmprovider/azure.png";
-import LocalAiLogo from "@/media/llmprovider/localai.png";
-import System from "@/models/system";
-import PreLoader from "@/components/Preloader";
-import LLMProviderOption from "@/components/LLMSelection/LLMProviderOption";
-import OpenAiOptions from "@/components/EmbeddingSelection/OpenAiOptions";
-import AzureAiOptions from "@/components/EmbeddingSelection/AzureAiOptions";
-import LocalAiOptions from "@/components/EmbeddingSelection/LocalAiOptions";
-import NativeEmbeddingOptions from "@/components/EmbeddingSelection/NativeEmbeddingOptions";
-
-function EmbeddingSelection({ nextStep, prevStep, currentStep }) {
-  const [embeddingChoice, setEmbeddingChoice] = useState("native");
-  const [settings, setSettings] = useState(null);
-  const [loading, setLoading] = useState(true);
-  const updateChoice = (selection) => {
-    setEmbeddingChoice(selection);
-  };
-
-  useEffect(() => {
-    async function fetchKeys() {
-      const _settings = await System.keys();
-      setSettings(_settings);
-      setEmbeddingChoice(_settings?.EmbeddingEngine || "native");
-      setLoading(false);
-    }
-    fetchKeys();
-  }, [currentStep]);
-
-  const handleSubmit = async (e) => {
-    e.preventDefault();
-    const form = e.target;
-    const data = {};
-    const formData = new FormData(form);
-    for (var [key, value] of formData.entries()) data[key] = value;
-    const { error } = await System.updateSystem(data);
-    if (error) {
-      alert(`Failed to save LLM settings: ${error}`, "error");
-      return;
-    }
-    nextStep("vector_database");
-    return;
-  };
-
-  if (loading)
-    return (
-      <div className="w-full h-full flex justify-center items-center p-20">
-        <PreLoader />
-      </div>
-    );
-
-  return (
-    <div className="w-full">
-      <form onSubmit={handleSubmit} className="flex flex-col w-full">
-        <div className="flex flex-col w-full px-1 md:px-8 py-4">
-          <div className="text-white text-sm font-medium pb-4">
-            Embedding Provider
-          </div>
-          <div className="w-full flex md:flex-wrap overflow-x-scroll gap-4 max-w-[752px]">
-            <input
-              hidden={true}
-              name="EmbeddingEngine"
-              value={embeddingChoice}
-            />
-            <LLMProviderOption
-              name="AnythingLLM Embedder"
-              value="native"
-              description="Use the built-in embedding engine for AnythingLLM. Zero setup!"
-              checked={embeddingChoice === "native"}
-              image={AnythingLLMIcon}
-              onClick={updateChoice}
-            />
-            <LLMProviderOption
-              name="OpenAI"
-              value="openai"
-              link="openai.com"
-              description="The standard option for most non-commercial use."
-              checked={embeddingChoice === "openai"}
-              image={OpenAiLogo}
-              onClick={updateChoice}
-            />
-            <LLMProviderOption
-              name="Azure OpenAI"
-              value="azure"
-              link="azure.microsoft.com"
-              description="The enterprise option of OpenAI hosted on Azure services."
-              checked={embeddingChoice === "azure"}
-              image={AzureOpenAiLogo}
-              onClick={updateChoice}
-            />
-            <LLMProviderOption
-              name="LocalAI"
-              value="localai"
-              link="localai.io"
-              description="Self hosted LocalAI embedding engine."
-              checked={embeddingChoice === "localai"}
-              image={LocalAiLogo}
-              onClick={updateChoice}
-            />
-          </div>
-          <div className="mt-4 flex flex-wrap gap-4 max-w-[752px]">
-            {embeddingChoice === "native" && <NativeEmbeddingOptions />}
-            {embeddingChoice === "openai" && (
-              <OpenAiOptions settings={settings} />
-            )}
-            {embeddingChoice === "azure" && (
-              <AzureAiOptions settings={settings} />
-            )}
-            {embeddingChoice === "localai" && (
-              <LocalAiOptions settings={settings} />
-            )}
-          </div>
-        </div>
-        <div className="flex w-full justify-between items-center px-6 py-4 space-x-2 border-t rounded-b border-gray-500/50">
-          <button
-            onClick={prevStep}
-            type="button"
-            className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-          >
-            Back
-          </button>
-          <button
-            type="submit"
-            className="border border-slate-200 px-4 py-2 rounded-lg text-slate-800 bg-slate-200 text-sm items-center flex gap-x-2 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow"
-          >
-            Continue
-          </button>
-        </div>
-      </form>
-    </div>
-  );
-}
-
-export default memo(EmbeddingSelection);
diff --git a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/LLMSelection/index.jsx b/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/LLMSelection/index.jsx
deleted file mode 100644
index 850dea3c2ec8b86a21678b8c8fdd7403994c9c7c..0000000000000000000000000000000000000000
--- a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/LLMSelection/index.jsx
+++ /dev/null
@@ -1,183 +0,0 @@
-import React, { memo, useEffect, useState } from "react";
-import AnythingLLMIcon from "@/media/logo/anything-llm-icon.png";
-import OpenAiLogo from "@/media/llmprovider/openai.png";
-import AzureOpenAiLogo from "@/media/llmprovider/azure.png";
-import AnthropicLogo from "@/media/llmprovider/anthropic.png";
-import GeminiLogo from "@/media/llmprovider/gemini.png";
-import OllamaLogo from "@/media/llmprovider/ollama.png";
-import LMStudioLogo from "@/media/llmprovider/lmstudio.png";
-import LocalAiLogo from "@/media/llmprovider/localai.png";
-import System from "@/models/system";
-import PreLoader from "@/components/Preloader";
-import LLMProviderOption from "@/components/LLMSelection/LLMProviderOption";
-import OpenAiOptions from "@/components/LLMSelection/OpenAiOptions";
-import AzureAiOptions from "@/components/LLMSelection/AzureAiOptions";
-import AnthropicAiOptions from "@/components/LLMSelection/AnthropicAiOptions";
-import LMStudioOptions from "@/components/LLMSelection/LMStudioOptions";
-import LocalAiOptions from "@/components/LLMSelection/LocalAiOptions";
-import NativeLLMOptions from "@/components/LLMSelection/NativeLLMOptions";
-import GeminiLLMOptions from "@/components/LLMSelection/GeminiLLMOptions";
-import OllamaLLMOptions from "@/components/LLMSelection/OllamaLLMOptions";
-
-function LLMSelection({ nextStep, prevStep, currentStep }) {
-  const [llmChoice, setLLMChoice] = useState("openai");
-  const [settings, setSettings] = useState(null);
-  const [loading, setLoading] = useState(true);
-
-  const updateLLMChoice = (selection) => {
-    setLLMChoice(selection);
-  };
-
-  useEffect(() => {
-    async function fetchKeys() {
-      const _settings = await System.keys();
-      setSettings(_settings);
-      setLLMChoice(_settings?.LLMProvider || "openai");
-      setLoading(false);
-    }
-
-    if (currentStep === "llm_preference") {
-      fetchKeys();
-    }
-  }, []);
-
-  const handleSubmit = async (e) => {
-    e.preventDefault();
-    const form = e.target;
-    const data = {};
-    const formData = new FormData(form);
-    for (var [key, value] of formData.entries()) data[key] = value;
-    const { error } = await System.updateSystem(data);
-    if (error) {
-      alert(`Failed to save LLM settings: ${error}`, "error");
-      return;
-    }
-    nextStep("embedding_preferences");
-  };
-
-  if (loading)
-    return (
-      <div className="w-full h-full flex justify-center items-center p-20">
-        <PreLoader />
-      </div>
-    );
-
-  return (
-    <div>
-      <form onSubmit={handleSubmit} className="flex flex-col w-full">
-        <div className="flex flex-col w-full px-1 md:px-8 py-4">
-          <div className="text-white text-sm font-medium pb-4">
-            LLM Providers
-          </div>
-          <div className="w-full flex md:flex-wrap overflow-x-scroll gap-4 max-w-[752px]">
-            <input hidden={true} name="LLMProvider" value={llmChoice} />
-            <LLMProviderOption
-              name="OpenAI"
-              value="openai"
-              link="openai.com"
-              description="The standard option for most non-commercial use."
-              checked={llmChoice === "openai"}
-              image={OpenAiLogo}
-              onClick={updateLLMChoice}
-            />
-            <LLMProviderOption
-              name="Azure OpenAI"
-              value="azure"
-              link="azure.microsoft.com"
-              description="The enterprise option of OpenAI hosted on Azure services."
-              checked={llmChoice === "azure"}
-              image={AzureOpenAiLogo}
-              onClick={updateLLMChoice}
-            />
-            <LLMProviderOption
-              name="Anthropic Claude 2"
-              value="anthropic"
-              link="anthropic.com"
-              description="A friendly AI Assistant hosted by Anthropic. Provides chat services only!"
-              checked={llmChoice === "anthropic"}
-              image={AnthropicLogo}
-              onClick={updateLLMChoice}
-            />
-            <LLMProviderOption
-              name="Google Gemini"
-              value="gemini"
-              link="ai.google.dev"
-              description="Google's largest and most capable AI model"
-              checked={llmChoice === "gemini"}
-              image={GeminiLogo}
-              onClick={updateLLMChoice}
-            />
-            <LLMProviderOption
-              name="LM Studio"
-              value="lmstudio"
-              link="lmstudio.ai"
-              description="Discover, download, and run thousands of cutting edge LLMs in a few clicks."
-              checked={llmChoice === "lmstudio"}
-              image={LMStudioLogo}
-              onClick={updateLLMChoice}
-            />
-            <LLMProviderOption
-              name="Local AI"
-              value="localai"
-              link="localai.io"
-              description="Run LLMs locally on your own machine."
-              checked={llmChoice === "localai"}
-              image={LocalAiLogo}
-              onClick={updateLLMChoice}
-            />
-            <LLMProviderOption
-              name="Ollama"
-              value="ollama"
-              link="ollama.ai"
-              description="Run LLMs locally on your own machine."
-              checked={llmChoice === "ollama"}
-              image={OllamaLogo}
-              onClick={updateLLMChoice}
-            />
-            {!window.location.hostname.includes("useanything.com") && (
-              <LLMProviderOption
-                name="Custom Llama Model"
-                value="native"
-                description="Use a downloaded custom Llama model for chatting on this AnythingLLM instance."
-                checked={llmChoice === "native"}
-                image={AnythingLLMIcon}
-                onClick={updateLLMChoice}
-              />
-            )}
-          </div>
-          <div className="mt-4 flex flex-wrap gap-4 max-w-[752px]">
-            {llmChoice === "openai" && <OpenAiOptions settings={settings} />}
-            {llmChoice === "azure" && <AzureAiOptions settings={settings} />}
-            {llmChoice === "anthropic" && (
-              <AnthropicAiOptions settings={settings} />
-            )}
-            {llmChoice === "gemini" && <GeminiLLMOptions settings={settings} />}
-            {llmChoice === "lmstudio" && (
-              <LMStudioOptions settings={settings} />
-            )}
-            {llmChoice === "localai" && <LocalAiOptions settings={settings} />}
-            {llmChoice === "ollama" && <OllamaLLMOptions settings={settings} />}
-            {llmChoice === "native" && <NativeLLMOptions settings={settings} />}
-          </div>
-        </div>
-        <div className="flex w-full justify-between items-center px-6 py-4 space-x-2 border-t rounded-b border-gray-500/50">
-          <button
-            onClick={prevStep}
-            type="button"
-            className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-          >
-            Back
-          </button>
-          <button
-            type="submit"
-            className="border border-slate-200 px-4 py-2 rounded-lg text-slate-800 bg-slate-200 text-sm items-center flex gap-x-2 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow"
-          >
-            Continue
-          </button>
-        </div>
-      </form>
-    </div>
-  );
-}
-
-export default memo(LLMSelection);
diff --git a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/MultiUserSetup/index.jsx b/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/MultiUserSetup/index.jsx
deleted file mode 100644
index 71310abfcae012dfe190a9b7ea3871a1d3a0e72b..0000000000000000000000000000000000000000
--- a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/MultiUserSetup/index.jsx
+++ /dev/null
@@ -1,117 +0,0 @@
-import React, { useState, memo } from "react";
-import System from "@/models/system";
-import { AUTH_TIMESTAMP, AUTH_TOKEN, AUTH_USER } from "@/utils/constants";
-import debounce from "lodash.debounce";
-
-// Multi-user mode step
-function MultiUserSetup({ nextStep, prevStep }) {
-  const [username, setUsername] = useState("");
-  const [password, setPassword] = useState("");
-
-  const handleSubmit = async (e) => {
-    e.preventDefault();
-    const form = e.target;
-    const formData = new FormData(form);
-    const data = {
-      username: formData.get("username"),
-      password: formData.get("password"),
-    };
-    const { success, error } = await System.setupMultiUser(data);
-    if (!success) {
-      alert(error);
-      return;
-    }
-
-    // Auto-request token with credentials that was just set so they
-    // are not redirected to login after completion.
-    const { user, token } = await System.requestToken(data);
-    window.localStorage.setItem(AUTH_USER, JSON.stringify(user));
-    window.localStorage.setItem(AUTH_TOKEN, token);
-    window.localStorage.removeItem(AUTH_TIMESTAMP);
-
-    nextStep("data_handling");
-  };
-
-  const setNewUsername = (e) => setUsername(e.target.value);
-  const setNewPassword = (e) => setPassword(e.target.value);
-  const handleUsernameChange = debounce(setNewUsername, 500);
-  const handlePasswordChange = debounce(setNewPassword, 500);
-  return (
-    <div>
-      <form onSubmit={handleSubmit}>
-        <div className="flex flex-col w-full md:px-8 py-4">
-          <div className="space-y-6 flex h-full w-96">
-            <div className="w-full flex flex-col gap-y-4">
-              <div>
-                <label
-                  htmlFor="name"
-                  className="block mb-2 text-sm font-medium text-white"
-                >
-                  Admin account username
-                </label>
-                <input
-                  name="username"
-                  type="text"
-                  className="bg-zinc-900 border border-gray-500 text-white text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
-                  placeholder="Your admin username"
-                  minLength={6}
-                  required={true}
-                  autoComplete="off"
-                  onChange={handleUsernameChange}
-                />
-              </div>
-              <div>
-                <label
-                  htmlFor="name"
-                  className="block mb-2 text-sm font-medium text-white"
-                >
-                  Admin account password
-                </label>
-                <input
-                  name="password"
-                  type="password"
-                  className="bg-zinc-900 border border-gray-500 text-white text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
-                  placeholder="Your admin password"
-                  minLength={8}
-                  required={true}
-                  autoComplete="off"
-                  onChange={handlePasswordChange}
-                />
-              </div>
-              <p className="w-96 text-white text-opacity-80 text-xs font-base">
-                Username must be at least 6 characters long. Password must be at
-                least 8 characters long.
-              </p>
-            </div>
-          </div>
-        </div>
-        <div className="flex w-full justify-between items-center px-6 py-4 space-x-6 border-t rounded-b border-gray-500/50">
-          <div className="w-96 text-white text-opacity-80 text-xs font-base">
-            By default, you will be the only admin. As an admin you will need to
-            create accounts for all new users or admins. Do not lose your
-            password as only admins can reset passwords.
-          </div>
-          <div className="flex gap-2">
-            <button
-              onClick={prevStep}
-              type="button"
-              className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-            >
-              Back
-            </button>
-            <button
-              type="submit"
-              className="border px-4 py-2 rounded-lg text-sm items-center flex gap-x-2
-              border-slate-200 text-slate-800 bg-slate-200 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow
-              disabled:border-gray-400 disabled:text-slate-800 disabled:bg-gray-400 disabled:cursor-not-allowed"
-              disabled={!(!!username && !!password)}
-            >
-              Continue
-            </button>
-          </div>
-        </div>
-      </form>
-    </div>
-  );
-}
-export default memo(MultiUserSetup);
diff --git a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/PasswordProtection/index.jsx b/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/PasswordProtection/index.jsx
deleted file mode 100644
index 4504288e6a95b82695c0737daae452b515ca9d5e..0000000000000000000000000000000000000000
--- a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/PasswordProtection/index.jsx
+++ /dev/null
@@ -1,103 +0,0 @@
-import React, { memo, useState } from "react";
-import System from "@/models/system";
-import { AUTH_TIMESTAMP, AUTH_TOKEN, AUTH_USER } from "@/utils/constants";
-import debounce from "lodash.debounce";
-
-function PasswordProtection({ nextStep, prevStep }) {
-  const [password, setPassword] = useState("");
-  const handleSubmit = async (e) => {
-    e.preventDefault();
-    const form = e.target;
-    const formData = new FormData(form);
-    const { error } = await System.updateSystemPassword({
-      usePassword: true,
-      newPassword: formData.get("password"),
-    });
-
-    if (error) {
-      alert(`Failed to set password: ${error}`, "error");
-      return;
-    }
-
-    // Auto-request token with password that was just set so they
-    // are not redirected to login after completion.
-    const { token } = await System.requestToken({
-      password: formData.get("password"),
-    });
-    window.localStorage.removeItem(AUTH_USER);
-    window.localStorage.removeItem(AUTH_TIMESTAMP);
-    window.localStorage.setItem(AUTH_TOKEN, token);
-
-    nextStep("data_handling");
-    return;
-  };
-
-  const handleSkip = () => {
-    nextStep("data_handling");
-  };
-
-  const setNewPassword = (e) => setPassword(e.target.value);
-  const handlePasswordChange = debounce(setNewPassword, 500);
-  return (
-    <div className="w-full">
-      <form className="flex flex-col w-full" onSubmit={handleSubmit}>
-        <div className="flex flex-col w-full px-1 md:px-8 py-4">
-          <div className="w-full flex flex-col gap-y-2 my-5">
-            <div className="w-80">
-              <div className="flex flex-col mb-3 ">
-                <label
-                  htmlFor="password"
-                  className="block font-medium text-white"
-                >
-                  New Password
-                </label>
-                <p className="text-slate-300 text-xs">
-                  must be at least 8 characters.
-                </p>
-              </div>
-              <input
-                onChange={handlePasswordChange}
-                name="password"
-                type="text"
-                className="bg-zinc-900 text-white text-sm rounded-lg focus:border-blue-500 block w-full p-2.5 placeholder-white placeholder-opacity-60 focus:ring-blue-500"
-                placeholder="Your Instance Password"
-                minLength={8}
-                required={true}
-                autoComplete="off"
-              />
-            </div>
-          </div>
-        </div>
-        <div className="flex w-full justify-between items-center px-6 py-4 space-x-2 border-t rounded-b border-gray-500/50">
-          <button
-            onClick={prevStep}
-            type="button"
-            className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-          >
-            Back
-          </button>
-
-          <div className="flex gap-2">
-            <button
-              onClick={handleSkip}
-              type="button"
-              className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-            >
-              Skip
-            </button>
-            <button
-              type="submit"
-              disabled={!password}
-              className="border px-4 py-2 rounded-lg text-sm items-center flex gap-x-2
-              border-slate-200 text-slate-800 bg-slate-200 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow
-              disabled:border-gray-400 disabled:text-slate-800 disabled:bg-gray-400 disabled:cursor-not-allowed"
-            >
-              Continue
-            </button>
-          </div>
-        </div>
-      </form>
-    </div>
-  );
-}
-export default memo(PasswordProtection);
diff --git a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/UserModeSelection/index.jsx b/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/UserModeSelection/index.jsx
deleted file mode 100644
index b78c325330838dc91aa448bdde100c145792440e..0000000000000000000000000000000000000000
--- a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/UserModeSelection/index.jsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import React, { memo } from "react";
-
-// How many people will be using your instance step
-function UserModeSelection({ nextStep, prevStep }) {
-  const justMeClicked = () => {
-    nextStep("password_protection");
-  };
-
-  const myTeamClicked = () => {
-    nextStep("multi_user_mode");
-  };
-
-  return (
-    <div>
-      <div className="flex flex-col justify-center items-center px-20 py-14">
-        <div className="w-80 text-white text-center text-2xl font-base">
-          How many people will be using your instance?
-        </div>
-        <div className="flex gap-4 justify-center my-8">
-          <button
-            onClick={justMeClicked}
-            className="transition-all duration-200 border border-slate-200 px-4 py-2 rounded-lg text-slate-800 bg-slate-200 text-sm items-center flex gap-x-2 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow"
-          >
-            Just Me
-          </button>
-          <button
-            onClick={myTeamClicked}
-            className="transition-all duration-200 border border-slate-200 px-5 py-2.5 rounded-lg text-slate-800 bg-slate-200 text-sm items-center flex gap-x-2 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow"
-          >
-            My Team
-          </button>
-        </div>
-      </div>
-      <div className="flex w-full justify-between items-center p-6 space-x-2 border-t rounded-b border-gray-500/50">
-        <button
-          onClick={prevStep}
-          type="button"
-          className="px-4 py-2 rounded-lg text-white hover:bg-sidebar transition-all duration-300"
-        >
-          Back
-        </button>
-      </div>
-    </div>
-  );
-}
-
-export default memo(UserModeSelection);
diff --git a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/UserQuestionnaire/index.jsx b/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/UserQuestionnaire/index.jsx
deleted file mode 100644
index a0cb97fd75c119facb73ee480fc01386e9502503..0000000000000000000000000000000000000000
--- a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/UserQuestionnaire/index.jsx
+++ /dev/null
@@ -1,240 +0,0 @@
-import { COMPLETE_QUESTIONNAIRE } from "@/utils/constants";
-import paths from "@/utils/paths";
-import { CheckCircle, Circle } from "@phosphor-icons/react";
-import React, { memo } from "react";
-
-async function sendQuestionnaire({ email, useCase, comment }) {
-  if (import.meta.env.DEV) return;
-  return fetch(`https://onboarding-wxich7363q-uc.a.run.app`, {
-    method: "POST",
-    body: JSON.stringify({
-      email,
-      useCase,
-      comment,
-      sourceId: "0VRjqHh6Vukqi0x0Vd0n/m8JuT7k8nOz",
-    }),
-  })
-    .then(() => {
-      window.localStorage.setItem(COMPLETE_QUESTIONNAIRE, true);
-      console.log(`✅ Questionnaire responses sent.`);
-    })
-    .catch((error) => {
-      console.error(`sendQuestionnaire`, error.message);
-    });
-}
-
-function UserQuestionnaire({ nextStep, prevStep }) {
-  const handleSubmit = async (e) => {
-    e.preventDefault();
-    const form = e.target;
-    const formData = new FormData(form);
-    nextStep("create_workspace");
-
-    await sendQuestionnaire({
-      email: formData.get("email"),
-      useCase: formData.get("use_case") || "other",
-      comment: formData.get("comment") || null,
-    });
-    return;
-  };
-
-  const handleSkip = () => {
-    nextStep("create_workspace");
-  };
-
-  if (!!window?.localStorage?.getItem(COMPLETE_QUESTIONNAIRE)) {
-    return (
-      <div className="w-full">
-        <div className="w-full flex items-center justify-center px-1 md:px-8 py-4">
-          <div className="w-auto flex flex-col gap-y-1 items-center">
-            <CheckCircle size={60} className="text-green-500" />
-            <p className="text-zinc-300">Thank you for your feedback!</p>
-            <a
-              href={paths.mailToMintplex()}
-              className="text-blue-400 underline text-xs"
-            >
-              team@mintplexlabs.com
-            </a>
-          </div>
-        </div>
-
-        <div className="flex w-full justify-between items-center px-6 py-4 space-x-2 border-t rounded-b border-gray-500/50">
-          <button
-            onClick={prevStep}
-            type="button"
-            className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-          >
-            Back
-          </button>
-
-          <div className="flex gap-2">
-            <button
-              onClick={handleSkip}
-              type="button"
-              className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-            >
-              Skip
-            </button>
-            <button
-              type="submit"
-              className="border px-4 py-2 rounded-lg text-sm items-center flex gap-x-2
-              border-slate-200 text-slate-800 bg-slate-200 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow
-              disabled:border-gray-400 disabled:text-slate-800 disabled:bg-gray-400 disabled:cursor-not-allowed"
-            >
-              Continue
-            </button>
-          </div>
-        </div>
-      </div>
-    );
-  }
-
-  return (
-    <div className="w-full">
-      <form className="flex flex-col w-full" onSubmit={handleSubmit}>
-        <div className="flex flex-col w-full px-1 md:px-8 py-4">
-          <div className="w-full flex flex-col gap-y-2 my-5">
-            <div className="w-80">
-              <div className="flex flex-col mb-3 ">
-                <label htmlFor="email" className="block font-medium text-white">
-                  What is your email?
-                </label>
-              </div>
-              <input
-                name="email"
-                type="email"
-                className="bg-zinc-900 text-white text-sm rounded-lg focus:border-blue-500 block w-full p-2.5 placeholder-white placeholder-opacity-60 focus:ring-blue-500"
-                placeholder="you@gmail.com"
-                required={true}
-                autoComplete="off"
-              />
-            </div>
-          </div>
-
-          <div className="w-full flex flex-col gap-y-2 my-5">
-            <div className="w-full">
-              <div className="flex flex-col mb-3 ">
-                <label
-                  htmlFor="use_case"
-                  className="block font-medium text-white"
-                >
-                  How are you planning to use AnythingLLM?
-                </label>
-              </div>
-
-              <div className="flex flex-col gap-y-2">
-                <div class="flex items-center ps-4 border border-zinc-400 rounded group radio-container hover:bg-blue-400/10">
-                  <input
-                    id="bordered-radio-1"
-                    type="radio"
-                    value="business"
-                    name="use_case"
-                    class="sr-only peer"
-                  />
-                  <Circle
-                    weight="fill"
-                    className="fill-transparent border border-gray-300 rounded-full peer-checked:fill-blue-500 peer-checked:border-none"
-                  />
-                  <label
-                    for="bordered-radio-1"
-                    class="w-full py-4 ms-2 text-sm font-medium text-gray-300"
-                  >
-                    For my business
-                  </label>
-                </div>
-                <div class="flex items-center ps-4 border border-zinc-400 rounded group radio-container hover:bg-blue-400/10">
-                  <input
-                    id="bordered-radio-2"
-                    type="radio"
-                    value="personal"
-                    name="use_case"
-                    class="sr-only peer"
-                  />
-                  <Circle
-                    weight="fill"
-                    className="fill-transparent border border-gray-300 rounded-full peer-checked:fill-blue-500 peer-checked:border-none"
-                  />
-                  <label
-                    for="bordered-radio-2"
-                    class="w-full py-4 ms-2 text-sm font-medium text-gray-300"
-                  >
-                    For personal use
-                  </label>
-                </div>
-                <div class="flex items-center ps-4 border border-zinc-400 rounded group radio-container hover:bg-blue-400/10">
-                  <input
-                    id="bordered-radio-3"
-                    type="radio"
-                    value="other"
-                    name="use_case"
-                    class="sr-only peer"
-                  />
-                  <Circle
-                    weight="fill"
-                    className="fill-transparent border border-gray-300 rounded-full peer-checked:fill-blue-500 peer-checked:border-none"
-                  />
-                  <label
-                    for="bordered-radio-3"
-                    class="w-full py-4 ms-2 text-sm font-medium text-gray-300"
-                  >
-                    I'm not sure yet
-                  </label>
-                </div>
-              </div>
-            </div>
-          </div>
-
-          <div className="w-full flex flex-col gap-y-2 my-5">
-            <div className="w-full">
-              <div className="flex flex-col mb-3 ">
-                <label
-                  htmlFor="comments"
-                  className="block font-medium text-white"
-                >
-                  Any comments for the team?
-                </label>
-              </div>
-              <textarea
-                name="comment"
-                rows={5}
-                className="bg-zinc-900 text-white text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
-                placeholder="If you have any questions or comments right now, you can leave them here and we will get back to you. You can also email team@mintplexlabs.com"
-                wrap="soft"
-                autoComplete="off"
-              />
-            </div>
-          </div>
-        </div>
-
-        <div className="flex w-full justify-between items-center px-6 py-4 space-x-2 border-t rounded-b border-gray-500/50">
-          <button
-            onClick={prevStep}
-            type="button"
-            className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-          >
-            Back
-          </button>
-
-          <div className="flex gap-2">
-            <button
-              onClick={handleSkip}
-              type="button"
-              className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-            >
-              Skip
-            </button>
-            <button
-              type="submit"
-              className="border px-4 py-2 rounded-lg text-sm items-center flex gap-x-2
-              border-slate-200 text-slate-800 bg-slate-200 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow
-              disabled:border-gray-400 disabled:text-slate-800 disabled:bg-gray-400 disabled:cursor-not-allowed"
-            >
-              Continue
-            </button>
-          </div>
-        </div>
-      </form>
-    </div>
-  );
-}
-export default memo(UserQuestionnaire);
diff --git a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/VectorDatabaseConnection/index.jsx b/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/VectorDatabaseConnection/index.jsx
deleted file mode 100644
index 16ee9aa53b3f8cdaf571b432d5e5c37bef94a35b..0000000000000000000000000000000000000000
--- a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/VectorDatabaseConnection/index.jsx
+++ /dev/null
@@ -1,310 +0,0 @@
-import React, { memo, useEffect, useState } from "react";
-
-import VectorDBOption from "@/components/VectorDBOption";
-import ChromaLogo from "@/media/vectordbs/chroma.png";
-import PineconeLogo from "@/media/vectordbs/pinecone.png";
-import LanceDbLogo from "@/media/vectordbs/lancedb.png";
-import WeaviateLogo from "@/media/vectordbs/weaviate.png";
-import QDrantLogo from "@/media/vectordbs/qdrant.png";
-import System from "@/models/system";
-import PreLoader from "@/components/Preloader";
-
-function VectorDatabaseConnection({ nextStep, prevStep, currentStep }) {
-  const [vectorDB, setVectorDB] = useState("lancedb");
-  const [settings, setSettings] = useState({});
-  const [loading, setLoading] = useState(true);
-
-  useEffect(() => {
-    async function fetchKeys() {
-      const _settings = await System.keys();
-      setSettings(_settings);
-      setVectorDB(_settings?.VectorDB || "lancedb");
-      setLoading(false);
-    }
-    if (currentStep === "vector_database") {
-      fetchKeys();
-    }
-  }, [currentStep]);
-
-  const updateVectorChoice = (selection) => {
-    setVectorDB(selection);
-  };
-
-  const handleSubmit = async (e, formElement) => {
-    e.preventDefault();
-    const form = formElement || e.target;
-    const data = {};
-    const formData = new FormData(form);
-    for (var [key, value] of formData.entries()) data[key] = value;
-    const { error } = await System.updateSystem(data);
-    if (error) {
-      alert(`Failed to save settings: ${error}`, "error");
-      return;
-    }
-    nextStep("appearance");
-    return;
-  };
-
-  if (loading)
-    return (
-      <div className="w-full h-full flex justify-center items-center p-20">
-        <PreLoader />
-      </div>
-    );
-
-  return (
-    <div>
-      <form onSubmit={handleSubmit} className="flex flex-col w-full">
-        <div className="flex flex-col w-full px-1 md:px-8 py-4">
-          <div className="text-white text-sm font-medium pb-4">
-            Select your preferred vector database provider
-          </div>
-          <div className="w-full flex md:flex-wrap overflow-x-scroll gap-4 max-w-[752px]">
-            <input hidden={true} name="VectorDB" value={vectorDB} />
-            <VectorDBOption
-              name="Chroma"
-              value="chroma"
-              link="trychroma.com"
-              description="Open source vector database you can host yourself or on the cloud."
-              checked={vectorDB === "chroma"}
-              image={ChromaLogo}
-              onClick={updateVectorChoice}
-            />
-            <VectorDBOption
-              name="Pinecone"
-              value="pinecone"
-              link="pinecone.io"
-              description="100% cloud-based vector database for enterprise use cases."
-              checked={vectorDB === "pinecone"}
-              image={PineconeLogo}
-              onClick={updateVectorChoice}
-            />
-            <VectorDBOption
-              name="QDrant"
-              value="qdrant"
-              link="qdrant.tech"
-              description="Open source local and distributed cloud vector database."
-              checked={vectorDB === "qdrant"}
-              image={QDrantLogo}
-              onClick={updateVectorChoice}
-            />
-            <VectorDBOption
-              name="Weaviate"
-              value="weaviate"
-              link="weaviate.io"
-              description="Open source local and cloud hosted multi-modal vector database."
-              checked={vectorDB === "weaviate"}
-              image={WeaviateLogo}
-              onClick={updateVectorChoice}
-            />
-            <VectorDBOption
-              name="LanceDB"
-              value="lancedb"
-              link="lancedb.com"
-              description="100% local vector DB that runs on the same instance as AnythingLLM."
-              checked={vectorDB === "lancedb"}
-              image={LanceDbLogo}
-              onClick={updateVectorChoice}
-            />
-          </div>
-          <div className="mt-4 flex flex-wrap gap-4 max-w-[752px]">
-            {vectorDB === "pinecone" && (
-              <>
-                <div className="flex flex-col w-60">
-                  <label className="text-white text-sm font-semibold block mb-4">
-                    Pinecone DB API Key
-                  </label>
-                  <input
-                    type="password"
-                    name="PineConeKey"
-                    className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-                    placeholder="Pinecone API Key"
-                    defaultValue={settings?.PineConeKey ? "*".repeat(20) : ""}
-                    required={true}
-                    autoComplete="off"
-                    spellCheck={false}
-                  />
-                </div>
-
-                <div className="flex flex-col w-60">
-                  <label className="text-white text-sm font-semibold block mb-4">
-                    Pinecone Index Environment
-                  </label>
-                  <input
-                    type="text"
-                    name="PineConeEnvironment"
-                    className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-                    placeholder="us-gcp-west-1"
-                    defaultValue={settings?.PineConeEnvironment}
-                    required={true}
-                    autoComplete="off"
-                    spellCheck={false}
-                  />
-                </div>
-
-                <div className="flex flex-col w-60">
-                  <label className="text-white text-sm font-semibold block mb-4">
-                    Pinecone Index Name
-                  </label>
-                  <input
-                    type="text"
-                    name="PineConeIndex"
-                    className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-                    placeholder="my-index"
-                    defaultValue={settings?.PineConeIndex}
-                    required={true}
-                    autoComplete="off"
-                    spellCheck={false}
-                  />
-                </div>
-              </>
-            )}
-
-            {vectorDB === "chroma" && (
-              <>
-                <div className="flex flex-col w-60">
-                  <label className="text-white text-sm font-semibold block mb-4">
-                    Chroma Endpoint
-                  </label>
-                  <input
-                    type="url"
-                    name="ChromaEndpoint"
-                    className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-                    placeholder="http://localhost:8000"
-                    defaultValue={settings?.ChromaEndpoint}
-                    required={true}
-                    autoComplete="off"
-                    spellCheck={false}
-                  />
-                </div>
-
-                <div className="flex flex-col w-60">
-                  <label className="text-white text-sm font-semibold block mb-4">
-                    API Header
-                  </label>
-                  <input
-                    name="ChromaApiHeader"
-                    autoComplete="off"
-                    type="text"
-                    defaultValue={settings?.ChromaApiHeader}
-                    className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-                    placeholder="X-Api-Key"
-                  />
-                </div>
-
-                <div className="flex flex-col w-60">
-                  <label className="text-white text-sm font-semibold block mb-4">
-                    API Key
-                  </label>
-                  <input
-                    name="ChromaApiKey"
-                    autoComplete="off"
-                    type="password"
-                    defaultValue={settings?.ChromaApiKey ? "*".repeat(20) : ""}
-                    className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-                    placeholder="sk-myApiKeyToAccessMyChromaInstance"
-                  />
-                </div>
-              </>
-            )}
-
-            {vectorDB === "lancedb" && (
-              <div className="w-full h-10 items-center justify-center flex">
-                <p className="text-sm font-base text-white text-opacity-60">
-                  There is no configuration needed for LanceDB.
-                </p>
-              </div>
-            )}
-
-            {vectorDB === "qdrant" && (
-              <>
-                <div className="flex flex-col w-60">
-                  <label className="text-white text-sm font-semibold block mb-4">
-                    QDrant API Endpoint
-                  </label>
-                  <input
-                    type="url"
-                    name="QdrantEndpoint"
-                    className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-                    placeholder="http://localhost:6633"
-                    defaultValue={settings?.QdrantEndpoint}
-                    required={true}
-                    autoComplete="off"
-                    spellCheck={false}
-                  />
-                </div>
-
-                <div className="flex flex-col w-60">
-                  <label className="text-white text-sm font-semibold block mb-4">
-                    API Key
-                  </label>
-                  <input
-                    type="password"
-                    name="QdrantApiKey"
-                    className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-                    placeholder="wOeqxsYP4....1244sba"
-                    defaultValue={settings?.QdrantApiKey}
-                    autoComplete="off"
-                    spellCheck={false}
-                  />
-                </div>
-              </>
-            )}
-
-            {vectorDB === "weaviate" && (
-              <>
-                <div className="flex flex-col w-60">
-                  <label className="text-white text-sm font-semibold block mb-4">
-                    Weaviate Endpoint
-                  </label>
-                  <input
-                    type="url"
-                    name="WeaviateEndpoint"
-                    className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-                    placeholder="http://localhost:8080"
-                    defaultValue={settings?.WeaviateEndpoint}
-                    required={true}
-                    autoComplete="off"
-                    spellCheck={false}
-                  />
-                </div>
-
-                <div className="flex flex-col w-60">
-                  <label className="text-white text-sm font-semibold block mb-4">
-                    API Key
-                  </label>
-                  <input
-                    type="password"
-                    name="WeaviateApiKey"
-                    className="bg-zinc-900 text-white placeholder-white placeholder-opacity-60 text-sm rounded-lg focus:border-white block w-full p-2.5"
-                    placeholder="sk-123Abcweaviate"
-                    defaultValue={settings?.WeaviateApiKey}
-                    autoComplete="off"
-                    spellCheck={false}
-                  />
-                </div>
-              </>
-            )}
-          </div>
-        </div>
-        <div className="flex w-full justify-between items-center px-6 py-4 space-x-2 border-t rounded-b border-gray-500/50">
-          <button
-            onClick={prevStep}
-            type="button"
-            className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-          >
-            Back
-          </button>
-          <button
-            type="submit"
-            className="border border-slate-200 px-4 py-2 rounded-lg text-slate-800 bg-slate-200 text-sm items-center flex gap-x-2 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow"
-          >
-            Continue
-          </button>
-        </div>
-      </form>
-    </div>
-  );
-}
-
-export default memo(VectorDatabaseConnection);
diff --git a/frontend/src/pages/OnboardingFlow/OnboardingModal/index.jsx b/frontend/src/pages/OnboardingFlow/OnboardingModal/index.jsx
deleted file mode 100644
index 9815a7e80dd1bbb7bee50827baaa6d93c22a1b8b..0000000000000000000000000000000000000000
--- a/frontend/src/pages/OnboardingFlow/OnboardingModal/index.jsx
+++ /dev/null
@@ -1,136 +0,0 @@
-import React, { useState } from "react";
-import { X } from "@phosphor-icons/react";
-import LLMSelection from "./Steps/LLMSelection";
-import VectorDatabaseConnection from "./Steps/VectorDatabaseConnection";
-import AppearanceSetup from "./Steps/AppearanceSetup";
-import UserModeSelection from "./Steps/UserModeSelection";
-import PasswordProtection from "./Steps/PasswordProtection";
-import MultiUserSetup from "./Steps/MultiUserSetup";
-import CreateFirstWorkspace from "./Steps/CreateFirstWorkspace";
-import EmbeddingSelection from "./Steps/EmbeddingSelection";
-import DataHandling from "./Steps/DataHandling";
-import UserQuestionnaire from "./Steps/UserQuestionnaire";
-
-const DIALOG_ID = "onboarding-modal";
-
-const STEPS = {
-  llm_preference: {
-    title: "LLM Preference",
-    description:
-      "These are the credentials and settings for your preferred LLM chat & embedding provider.",
-    component: LLMSelection,
-  },
-  embedding_preferences: {
-    title: "Embedding Preference",
-    description: "Choose a provider for embedding files and text.",
-    component: EmbeddingSelection,
-  },
-  vector_database: {
-    title: "Vector Database",
-    description:
-      "These are the credentials and settings for how your AnythingLLM instance will function.",
-    component: VectorDatabaseConnection,
-  },
-  appearance: {
-    title: "Appearance",
-    description:
-      "Customize the appearance of your AnythingLLM instance.\nFind more customization options on the appearance settings page.",
-    component: AppearanceSetup,
-  },
-  user_mode_setup: {
-    title: "User Mode Setup",
-    description: "Choose how many people will be using your instance.",
-    component: UserModeSelection,
-  },
-  password_protection: {
-    title: "Password Protect",
-    description:
-      "Protect your instance with a password. It is important to save this password as it cannot be recovered.",
-    component: PasswordProtection,
-  },
-  multi_user_mode: {
-    title: "Multi-User Mode",
-    description:
-      "Setup your instance to support your team by activating multi-user mode.",
-    component: MultiUserSetup,
-  },
-  data_handling: {
-    title: "Data Handling",
-    description:
-      "We are committed to transparency and control when it comes to your personal data.",
-    component: DataHandling,
-  },
-  user_questionnaire: {
-    title: "A little about yourself",
-    description:
-      "We use information about how you use AnythingLLM to make our product better.",
-    component: UserQuestionnaire,
-  },
-  create_workspace: {
-    title: "Create Workspace",
-    description: "To get started, create a new workspace.",
-    component: CreateFirstWorkspace,
-  },
-};
-
-export const OnboardingModalId = DIALOG_ID;
-export default function OnboardingModal({ setModalVisible }) {
-  const [currentStep, setCurrentStep] = useState("llm_preference");
-  const [history, setHistory] = useState(["llm_preference"]);
-
-  function hideModal() {
-    setModalVisible(false);
-  }
-
-  const nextStep = (stepKey) => {
-    setCurrentStep(stepKey);
-    setHistory([...history, stepKey]);
-  };
-
-  const prevStep = () => {
-    const currentStepIdx = history.indexOf(currentStep);
-    if (currentStepIdx === -1 || currentStepIdx === 0) {
-      setCurrentStep("llm_preference");
-      setHistory(["llm_preference"]);
-      return hideModal();
-    }
-
-    const prevStep = history[currentStepIdx - 1];
-    const _history = [...history].slice(0, currentStepIdx);
-    setCurrentStep(prevStep);
-    setHistory(_history);
-  };
-
-  const { component: StepComponent, ...step } = STEPS[currentStep];
-  return (
-    <dialog id={DIALOG_ID} className="bg-transparent outline-none">
-      <div className="relative max-h-full">
-        <div className="relative bg-main-gradient rounded-2xl shadow border-2 border-slate-300/10">
-          <div className="flex items-start justify-between px-6 py-4 border-b rounded-t border-gray-500/50">
-            <div className="flex flex-col gap-2">
-              <h3 className="text-xl font-semibold text-white">{step.title}</h3>
-              <p className="text-sm font-base text-white text-opacity-60 whitespace-pre">
-                {step.description || ""}
-              </p>
-            </div>
-
-            <button
-              onClick={hideModal}
-              type="button"
-              className="text-gray-400 bg-transparent rounded-lg text-sm p-1.5 ml-auto inline-flex items-center hover:border-white/60 bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
-            >
-              <X className="text-gray-300 text-lg" />
-            </button>
-          </div>
-          <div className="space-y-6 flex h-full w-full justify-center">
-            <StepComponent
-              currentStep={currentStep}
-              nextStep={nextStep}
-              prevStep={prevStep}
-            />
-          </div>
-        </div>
-      </div>
-    </dialog>
-  );
-}
diff --git a/frontend/src/pages/OnboardingFlow/Steps/CreateWorkspace/index.jsx b/frontend/src/pages/OnboardingFlow/Steps/CreateWorkspace/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..aa53c87fc4a9f2f3b02f87d8c0c3f0231269c336
--- /dev/null
+++ b/frontend/src/pages/OnboardingFlow/Steps/CreateWorkspace/index.jsx
@@ -0,0 +1,99 @@
+import React, { useEffect, useRef, useState } from "react";
+import illustration from "@/media/illustrations/create-workspace.png";
+import paths from "@/utils/paths";
+import showToast from "@/utils/toast";
+import { useNavigate } from "react-router-dom";
+import Workspace from "@/models/workspace";
+
+const TITLE = "Create your first workspace";
+const DESCRIPTION =
+  "Create your first workspace and get started with AnythingLLM.";
+
+export default function CreateWorkspace({
+  setHeader,
+  setForwardBtn,
+  setBackBtn,
+}) {
+  const [workspaceName, setWorkspaceName] = useState("");
+  const navigate = useNavigate();
+  const createWorkspaceRef = useRef();
+
+  useEffect(() => {
+    setHeader({ title: TITLE, description: DESCRIPTION });
+    setBackBtn({ showing: false, disabled: false, onClick: handleBack });
+  }, []);
+
+  useEffect(() => {
+    if (workspaceName.length > 3) {
+      setForwardBtn({ showing: true, disabled: false, onClick: handleForward });
+    } else {
+      setForwardBtn({ showing: true, disabled: true, onClick: handleForward });
+    }
+  }, [workspaceName]);
+
+  const handleCreate = async (e) => {
+    e.preventDefault();
+    const form = new FormData(e.target);
+    const { workspace, error } = await Workspace.new({
+      name: form.get("name"),
+      onboardingComplete: true,
+    });
+    if (!!workspace) {
+      showToast(
+        "Workspace created successfully! Taking you to home...",
+        "success"
+      );
+      await new Promise((resolve) => setTimeout(resolve, 1000));
+      navigate(paths.home());
+    } else {
+      showToast(`Failed to create workspace: ${error}`, "error");
+    }
+  };
+
+  function handleForward() {
+    createWorkspaceRef.current.click();
+  }
+
+  function handleBack() {
+    navigate(paths.onboarding.survey());
+  }
+
+  return (
+    <form
+      onSubmit={handleCreate}
+      className="w-full flex items-center justify-center flex-col gap-y-2"
+    >
+      <img src={illustration} alt="Create workspace" />
+      <div className="flex flex-col gap-y-4 w-full max-w-[600px]">
+        {" "}
+        <div className="w-full mt-4">
+          <label
+            htmlFor="name"
+            className="block mb-3 text-sm font-medium text-white"
+          >
+            Workspace Name
+          </label>
+          <input
+            name="name"
+            type="text"
+            className="bg-zinc-900 text-white text-sm rounded-lg block w-full p-2.5"
+            placeholder="My Workspace"
+            minLength={4}
+            required={true}
+            autoComplete="off"
+            onChange={(e) => setWorkspaceName(e.target.value)}
+          />
+          <div className="mt-4 text-white text-opacity-80 text-xs font-base -mb-2">
+            Workspace name must be at least 4 characters.
+          </div>
+        </div>
+      </div>
+      <button
+        type="submit"
+        ref={createWorkspaceRef}
+        hidden
+        aria-hidden="true"
+      ></button>
+    </form>
+  );
+}
diff --git a/frontend/src/pages/OnboardingFlow/Steps/CustomLogo/index.jsx b/frontend/src/pages/OnboardingFlow/Steps/CustomLogo/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..bb421bc39a953981f0349723dd2bb2fb9f7eda6f
--- /dev/null
+++ b/frontend/src/pages/OnboardingFlow/Steps/CustomLogo/index.jsx
@@ -0,0 +1,136 @@
+import useLogo from "@/hooks/useLogo";
+import System from "@/models/system";
+import showToast from "@/utils/toast";
+import { Plus } from "@phosphor-icons/react";
+import React, { useState, useEffect } from "react";
+import AnythingLLM from "@/media/logo/anything-llm.png";
+import paths from "@/utils/paths";
+import { useNavigate } from "react-router-dom";
+
+const TITLE = "Custom Logo";
+const DESCRIPTION =
+  "Upload your custom logo to make your chatbot yours. Optional.";
+
+export default function CustomLogo({ setHeader, setForwardBtn, setBackBtn }) {
+  const navigate = useNavigate();
+  function handleForward() {
+    navigate(paths.onboarding.userSetup());
+  }
+
+  function handleBack() {
+    navigate(paths.onboarding.vectorDatabase());
+  }
+
+  useEffect(() => {
+    setHeader({ title: TITLE, description: DESCRIPTION });
+    setForwardBtn({ showing: true, disabled: false, onClick: handleForward });
+    setBackBtn({ showing: true, disabled: false, onClick: handleBack });
+  }, []);
+
+  const { logo: _initLogo, setLogo: _setLogo } = useLogo();
+  const [logo, setLogo] = useState("");
+  const [isDefaultLogo, setIsDefaultLogo] = useState(true);
+
+  useEffect(() => {
+    async function logoInit() {
+      setLogo(_initLogo || "");
+      const _isDefaultLogo = await System.isDefaultLogo();
+      setIsDefaultLogo(_isDefaultLogo);
+    }
+    logoInit();
+  }, [_initLogo]);
+
+  const handleFileUpload = async (event) => {
+    const file = event.target.files[0];
+    if (!file) return false;
+
+    const objectURL = URL.createObjectURL(file);
+    setLogo(objectURL);
+
+    const formData = new FormData();
+    formData.append("logo", file);
+    const { success, error } = await System.uploadLogo(formData);
+    if (!success) {
+      showToast(`Failed to upload logo: ${error}`, "error");
+      setLogo(_initLogo);
+      return;
+    }
+
+    const logoURL = await System.fetchLogo();
+    _setLogo(logoURL);
+
+    showToast("Image uploaded successfully.", "success", { clear: true });
+    setIsDefaultLogo(false);
+  };
+
+  const handleRemoveLogo = async () => {
+    setLogo("");
+    setIsDefaultLogo(true);
+
+    const { success, error } = await System.removeCustomLogo();
+    if (!success) {
+      console.error("Failed to remove logo:", error);
+      showToast(`Failed to remove logo: ${error}`, "error");
+      const logoURL = await System.fetchLogo();
+      setLogo(logoURL);
+      setIsDefaultLogo(false);
+      return;
+    }
+
+    const logoURL = await System.fetchLogo();
+    _setLogo(logoURL);
+
+    showToast("Image successfully removed.", "success", { clear: true });
+  };
+
+  return (
+    <div className="flex items-center w-full">
+      <div className="flex gap-x-8 flex-col w-full">
+        {isDefaultLogo ? (
+          <label className="mt-5 hover:opacity-60 w-full flex justify-center transition-all duration-300">
+            <input
+              id="logo-upload"
+              type="file"
+              accept="image/*"
+              className="hidden"
+              onChange={handleFileUpload}
+            />
+            <div
+              className="max-w-[600px] w-full h-64 max-h-[600px] py-4 bg-zinc-900/50 rounded-2xl border-2 border-dashed border-white border-opacity-60 justify-center items-center inline-flex cursor-pointer"
+              htmlFor="logo-upload"
+            >
+              <div className="flex flex-col items-center justify-center">
+                <div className="rounded-full bg-white/40">
+                  <Plus className="w-6 h-6 text-black/80 m-2" />
+                </div>
+                <div className="text-white text-opacity-80 text-sm font-semibold py-1">
+                  Add a custom logo
+                </div>
+                <div className="text-white text-opacity-60 text-xs font-medium py-1">
+                  Recommended size: 800 x 200
+                </div>
+              </div>
+            </div>
+          </label>
+        ) : (
+          <div className="w-full flex justify-center">
+            <img
+              src={logo}
+              alt="Uploaded Logo"
+              className="w-48 h-48 object-contain mr-6"
+              hidden={isDefaultLogo}
+              onError={(e) => (e.target.src = AnythingLLM)}
+            />
+          </div>
+        )}
+
+        <button
+          onClick={handleRemoveLogo}
+          className="text-white text-base font-medium hover:text-opacity-60 mt-8"
+        >
+          Remove logo
+        </button>
+      </div>
+    </div>
+  );
+}
diff --git a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/DataHandling/index.jsx b/frontend/src/pages/OnboardingFlow/Steps/DataHandling/index.jsx
similarity index 87%
rename from frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/DataHandling/index.jsx
rename to frontend/src/pages/OnboardingFlow/Steps/DataHandling/index.jsx
index 81b93c5dc0952fb96e26c30dcf727c23d5c5b311..db285f128328c08c6fa8c3f8bed879eac5099fe1 100644
--- a/frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/DataHandling/index.jsx
+++ b/frontend/src/pages/OnboardingFlow/Steps/DataHandling/index.jsx
@@ -1,4 +1,4 @@
-import React, { memo, useEffect, useState } from "react";
+import PreLoader from "@/components/Preloader";
 import System from "@/models/system";
 import AnythingLLMIcon from "@/media/logo/anything-llm-icon.png";
 import OpenAiLogo from "@/media/llmprovider/openai.png";
@@ -13,8 +13,13 @@ import PineconeLogo from "@/media/vectordbs/pinecone.png";
 import LanceDbLogo from "@/media/vectordbs/lancedb.png";
 import WeaviateLogo from "@/media/vectordbs/weaviate.png";
 import QDrantLogo from "@/media/vectordbs/qdrant.png";
-import PreLoader from "@/components/Preloader";
+import React, { useState, useEffect } from "react";
+import paths from "@/utils/paths";
+import { useNavigate } from "react-router-dom";
 
+const TITLE = "Data Handling & Privacy";
+const DESCRIPTION =
+  "We are committed to transparency and control when it comes to your personal data.";
 const LLM_SELECTION_PRIVACY = {
   openai: {
     name: "OpenAI",
@@ -151,26 +156,36 @@ const EMBEDDING_ENGINE_PRIVACY = {
   },
 };
 
-function DataHandling({ nextStep, prevStep, currentStep }) {
+export default function DataHandling({ setHeader, setForwardBtn, setBackBtn }) {
   const [llmChoice, setLLMChoice] = useState("openai");
   const [loading, setLoading] = useState(true);
   const [vectorDb, setVectorDb] = useState("pinecone");
   const [embeddingEngine, setEmbeddingEngine] = useState("openai");
+  const navigate = useNavigate();
 
   useEffect(() => {
+    setHeader({ title: TITLE, description: DESCRIPTION });
+    setForwardBtn({ showing: true, disabled: false, onClick: handleForward });
+    setBackBtn({ showing: false, disabled: false, onClick: handleBack });
     async function fetchKeys() {
       const _settings = await System.keys();
-      setLLMChoice(_settings?.LLMProvider);
-      setVectorDb(_settings?.VectorDB);
-      setEmbeddingEngine(_settings?.EmbeddingEngine);
+      setLLMChoice(_settings?.LLMProvider || "openai");
+      setVectorDb(_settings?.VectorDB || "pinecone");
+      setEmbeddingEngine(_settings?.EmbeddingEngine || "openai");
 
       setLoading(false);
     }
-    if (currentStep === "data_handling") {
-      fetchKeys();
-    }
+    fetchKeys();
   }, []);
 
+  function handleForward() {
+    navigate(paths.onboarding.survey());
+  }
+
+  function handleBack() {
+    navigate(paths.onboarding.userSetup());
+  }
+
   if (loading)
     return (
       <div className="w-full h-full flex justify-center items-center p-20">
@@ -179,7 +194,7 @@ function DataHandling({ nextStep, prevStep, currentStep }) {
     );
 
   return (
-    <div className="max-w-[750px]">
+    <div className="w-full flex items-center justify-center flex-col gap-y-6">
       <div className="p-8 flex flex-col gap-8">
         <div className="flex flex-col gap-y-2 border-b border-zinc-500/50 pb-4">
           <div className="text-white text-base font-bold">LLM Selection</div>
@@ -239,23 +254,6 @@ function DataHandling({ nextStep, prevStep, currentStep }) {
           </ul>
         </div>
       </div>
-      <div className="flex w-[650px] justify-between items-center px-6 py-4 space-x-2 border-t rounded-b border-gray-500/50">
-        <button
-          onClick={prevStep}
-          type="button"
-          className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
-        >
-          Back
-        </button>
-        <button
-          onClick={() => nextStep("user_questionnaire")}
-          className="border border-slate-200 px-4 py-2 rounded-lg text-slate-800 bg-slate-200 text-sm items-center flex gap-x-2 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow"
-        >
-          Continue
-        </button>
-      </div>
     </div>
   );
 }
-
-export default memo(DataHandling);
diff --git a/frontend/src/pages/OnboardingFlow/Steps/EmbeddingPreference/EmbedderItem.jsx b/frontend/src/pages/OnboardingFlow/Steps/EmbeddingPreference/EmbedderItem.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..b37b645f95a282c129ecf199a9cdc72b7e60c06a
--- /dev/null
+++ b/frontend/src/pages/OnboardingFlow/Steps/EmbeddingPreference/EmbedderItem.jsx
@@ -0,0 +1,39 @@
+export default function EmbedderItem({
+  name,
+  value,
+  image,
+  description,
+  checked,
+  onClick,
+}) {
+  return (
+    <div
+      onClick={() => onClick(value)}
+      className={`w-full hover:bg-white/10 p-2 rounded-md hover:cursor-pointer ${
+        checked && "bg-white/10"
+      }`}
+    >
+      <input
+        type="checkbox"
+        value={value}
+        className="peer hidden"
+        checked={checked}
+        readOnly={true}
+        formNoValidate={true}
+      />
+      <div className="flex gap-x-4 items-center">
+        <img
+          src={image}
+          alt={`${name} logo`}
+          className="w-10 h-10 rounded-md"
+        />
+        <div className="flex flex-col gap-y-1">
+          <div className="text-sm font-semibold">{name}</div>
+          <div className="mt-2 text-xs text-white tracking-wide">
+            {description}
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git a/frontend/src/pages/OnboardingFlow/Steps/EmbeddingPreference/index.jsx b/frontend/src/pages/OnboardingFlow/Steps/EmbeddingPreference/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..c78d3f4434ba08b1693e863ca8a059f00ae7226e
--- /dev/null
+++ b/frontend/src/pages/OnboardingFlow/Steps/EmbeddingPreference/index.jsx
@@ -0,0 +1,180 @@
+import { MagnifyingGlass } from "@phosphor-icons/react";
+import { useEffect, useState, useRef } from "react";
+import AnythingLLMIcon from "@/media/logo/anything-llm-icon.png";
+import OpenAiLogo from "@/media/llmprovider/openai.png";
+import AzureOpenAiLogo from "@/media/llmprovider/azure.png";
+import LocalAiLogo from "@/media/llmprovider/localai.png";
+import NativeEmbeddingOptions from "@/components/EmbeddingSelection/NativeEmbeddingOptions";
+import OpenAiOptions from "@/components/EmbeddingSelection/OpenAiOptions";
+import AzureAiOptions from "@/components/EmbeddingSelection/AzureAiOptions";
+import LocalAiOptions from "@/components/EmbeddingSelection/LocalAiOptions";
+import EmbedderItem from "./EmbedderItem";
+import System from "@/models/system";
+import paths from "@/utils/paths";
+import showToast from "@/utils/toast";
+import { useNavigate } from "react-router-dom";
+
+const TITLE = "Embedding Preference";
+const DESCRIPTION =
+  "AnythingLLM can work with many embedding models. This will be the model which turns documents into vectors.";
+
+export default function EmbeddingPreference({
+  setHeader,
+  setForwardBtn,
+  setBackBtn,
+}) {
+  const [searchQuery, setSearchQuery] = useState("");
+  const [filteredEmbedders, setFilteredEmbedders] = useState([]);
+  const [selectedEmbedder, setSelectedEmbedder] = useState(null);
+  const [settings, setSettings] = useState(null);
+  const formRef = useRef(null);
+  const hiddenSubmitButtonRef = useRef(null);
+  const isHosted = window.location.hostname.includes("useanything.com");
+  const navigate = useNavigate();
+
+  useEffect(() => {
+    async function fetchKeys() {
+      const _settings = await System.keys();
+      setSettings(_settings);
+      setSelectedEmbedder(_settings?.EmbeddingEngine || "native");
+    }
+    fetchKeys();
+  }, []);
+
+  const EMBEDDERS = [
+    {
+      name: "AnythingLLM Embedder",
+      value: "native",
+      logo: AnythingLLMIcon,
+      options: <NativeEmbeddingOptions settings={settings} />,
+      description:
+        "Use the built-in embedding engine for AnythingLLM. Zero setup!",
+    },
+    {
+      name: "OpenAI",
+      value: "openai",
+      logo: OpenAiLogo,
+      options: <OpenAiOptions settings={settings} />,
+      description: "The standard option for most non-commercial use.",
+    },
+    {
+      name: "Azure OpenAI",
+      value: "azure",
+      logo: AzureOpenAiLogo,
+      options: <AzureAiOptions settings={settings} />,
+      description: "The enterprise option of OpenAI hosted on Azure services.",
+    },
+    {
+      name: "Local AI",
+      value: "localai",
+      logo: LocalAiLogo,
+      options: <LocalAiOptions settings={settings} />,
+      description: "Run embedding models locally on your own machine.",
+    },
+  ];
+
+  function handleForward() {
+    if (hiddenSubmitButtonRef.current) {
+      hiddenSubmitButtonRef.current.click();
+    }
+  }
+
+  function handleBack() {
+    navigate(paths.onboarding.llmPreference());
+  }
+
+  const handleSubmit = async (e) => {
+    e.preventDefault();
+    const form = e.target;
+    const data = {};
+    const formData = new FormData(form);
+    data.EmbeddingEngine = selectedEmbedder;
+    for (var [key, value] of formData.entries()) data[key] = value;
+
+    const { error } = await System.updateSystem(data);
+    if (error) {
+      showToast(`Failed to save embedding settings: ${error}`, "error");
+      return;
+    }
+    showToast("Embedder settings saved successfully.", "success", {
+      clear: true,
+    });
+    navigate(paths.onboarding.vectorDatabase());
+  };
+
+  useEffect(() => {
+    setHeader({ title: TITLE, description: DESCRIPTION });
+    setForwardBtn({ showing: true, disabled: false, onClick: handleForward });
+    setBackBtn({ showing: true, disabled: false, onClick: handleBack });
+  }, []);
+
+  useEffect(() => {
+    if (searchQuery.trim() === "") {
+      setFilteredEmbedders(EMBEDDERS);
+    } else {
+      const lowercasedQuery = searchQuery.toLowerCase();
+      const filtered = EMBEDDERS.filter((embedder) =>
+        embedder.name.toLowerCase().includes(lowercasedQuery)
+      );
+      setFilteredEmbedders(filtered);
+    }
+  }, [searchQuery]);
+
+  return (
+    <div>
+      <form ref={formRef} onSubmit={handleSubmit} className="w-full">
+        <div className="w-full relative border-slate-300/40 shadow border-2 rounded-lg text-white">
+          <div className="w-full p-4 absolute top-0 rounded-t-lg bg-accent/50">
+            <div className="w-full flex items-center sticky top-0 z-20">
+              <MagnifyingGlass
+                size={16}
+                weight="bold"
+                className="absolute left-4 z-30 text-white"
+              />
+              <input
+                type="text"
+                placeholder="Search Embedding providers"
+                className="bg-zinc-600 z-20 pl-10 rounded-full w-full px-4 py-1 text-sm border-2 border-slate-300/40 outline-none focus:border-white text-white"
+                onChange={(e) => setSearchQuery(e.target.value)}
+                autoComplete="off"
+                onKeyDown={(e) => {
+                  if (e.key === "Enter") e.preventDefault();
+                }}
+              />
+            </div>
+          </div>
+          <div className="px-4 pt-[70px] flex flex-col gap-y-1 max-h-[390px] overflow-y-auto no-scroll pb-4">
+            {filteredEmbedders.map((embedder) => {
+              if (embedder.value === "native" && isHosted) {
+                return null;
+              }
+
+              return (
+                <EmbedderItem
+                  key={embedder.name}
+                  name={embedder.name}
+                  value={embedder.value}
+                  image={embedder.logo}
+                  description={embedder.description}
+                  checked={selectedEmbedder === embedder.value}
+                  onClick={() => setSelectedEmbedder(embedder.value)}
+                />
+              );
+            })}
+          </div>
+        </div>
+        <div className="mt-4 flex flex-col gap-y-1">
+          {selectedEmbedder &&
+            EMBEDDERS.find((embedder) => embedder.value === selectedEmbedder)
+              ?.options}
+        </div>
+        <button
+          type="submit"
+          ref={hiddenSubmitButtonRef}
+          hidden
+          aria-hidden="true"
+        ></button>
+      </form>
+    </div>
+  );
+}
diff --git a/frontend/src/pages/OnboardingFlow/Steps/Home/index.jsx b/frontend/src/pages/OnboardingFlow/Steps/Home/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..7b31e2ac3db2bad94916f3cfc1740dd03e47c429
--- /dev/null
+++ b/frontend/src/pages/OnboardingFlow/Steps/Home/index.jsx
@@ -0,0 +1,41 @@
+import paths from "@/utils/paths";
+import LGroupImg from "./l_group.png";
+import RGroupImg from "./r_group.png";
+import AnythingLLMLogo from "@/media/logo/anything-llm.png";
+import { useNavigate } from "react-router-dom";
+
+export default function OnboardingHome() {
+  const navigate = useNavigate();
+  return (
+    <>
+      <div className="relative w-screen h-screen flex overflow-hidden bg-[#2C2F35] md:bg-main-gradient">
+        <div
+          className="hidden md:block fixed bottom-10 left-10 w-[320px] h-[320px] bg-no-repeat bg-contain"
+          style={{ backgroundImage: `url(${LGroupImg})` }}
+        ></div>
+
+        <div
+          className="hidden md:block fixed top-10 right-10 w-[320px] h-[320px] bg-no-repeat bg-contain"
+          style={{ backgroundImage: `url(${RGroupImg})` }}
+        ></div>
+
+        <div className="relative flex justify-center items-center m-auto">
+          <div className="flex flex-col justify-center items-center">
+            <p className="text-zinc-300 font-thin text-[24px]">Welcome to</p>
+            <img
+              src={AnythingLLMLogo}
+              alt="AnythingLLM"
+              className="md:h-[50px] flex-shrink-0 max-w-[300px]"
+            />
+            <button
+              onClick={() => navigate(paths.onboarding.llmPreference())}
+              className="animate-pulse w-full md:max-w-[350px] md:min-w-[300px] text-center py-3 bg-white text-black font-semibold text-sm my-10 rounded-md hover:bg-gray-200"
+            >
+              Get started
+            </button>
+          </div>
+        </div>
+      </div>
+    </>
+  );
+}
diff --git a/frontend/src/pages/OnboardingFlow/Steps/Home/l_group.png b/frontend/src/pages/OnboardingFlow/Steps/Home/l_group.png
new file mode 100644
index 0000000000000000000000000000000000000000..2981196a33208cdb5c6fa0a39b562176d42642e0
Binary files /dev/null and b/frontend/src/pages/OnboardingFlow/Steps/Home/l_group.png differ
diff --git a/frontend/src/pages/OnboardingFlow/Steps/Home/r_group.png b/frontend/src/pages/OnboardingFlow/Steps/Home/r_group.png
new file mode 100644
index 0000000000000000000000000000000000000000..fc50fd52c875578c55fa4e18d2143d0265ade213
Binary files /dev/null and b/frontend/src/pages/OnboardingFlow/Steps/Home/r_group.png differ
diff --git a/frontend/src/pages/OnboardingFlow/Steps/LLMPreference/LLMItem.jsx b/frontend/src/pages/OnboardingFlow/Steps/LLMPreference/LLMItem.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..b6db5d130376b84cb097ecfb25c248b982a2318e
--- /dev/null
+++ b/frontend/src/pages/OnboardingFlow/Steps/LLMPreference/LLMItem.jsx
@@ -0,0 +1,39 @@
+export default function LLMItem({
+  name,
+  value,
+  image,
+  description,
+  checked,
+  onClick,
+}) {
+  return (
+    <div
+      onClick={() => onClick(value)}
+      className={`w-full hover:bg-white/10 p-2 rounded-md hover:cursor-pointer ${
+        checked && "bg-white/10"
+      }`}
+    >
+      <input
+        type="checkbox"
+        value={value}
+        className="peer hidden"
+        checked={checked}
+        readOnly={true}
+        formNoValidate={true}
+      />
+      <div className="flex gap-x-4 items-center">
+        <img
+          src={image}
+          alt={`${name} logo`}
+          className="w-10 h-10 rounded-md"
+        />
+        <div className="flex flex-col gap-y-1">
+          <div className="text-sm font-semibold">{name}</div>
+          <div className="mt-2 text-xs text-white tracking-wide">
+            {description}
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git a/frontend/src/pages/OnboardingFlow/Steps/LLMPreference/index.jsx b/frontend/src/pages/OnboardingFlow/Steps/LLMPreference/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..24d561ed6d8d6256c6fc831e41f94593ec6ece01
--- /dev/null
+++ b/frontend/src/pages/OnboardingFlow/Steps/LLMPreference/index.jsx
@@ -0,0 +1,211 @@
+import { MagnifyingGlass } from "@phosphor-icons/react";
+import { useEffect, useState, useRef } from "react";
+import OpenAiLogo from "@/media/llmprovider/openai.png";
+import AzureOpenAiLogo from "@/media/llmprovider/azure.png";
+import AnthropicLogo from "@/media/llmprovider/anthropic.png";
+import GeminiLogo from "@/media/llmprovider/gemini.png";
+import OllamaLogo from "@/media/llmprovider/ollama.png";
+import LMStudioLogo from "@/media/llmprovider/lmstudio.png";
+import LocalAiLogo from "@/media/llmprovider/localai.png";
+import AnythingLLMIcon from "@/media/logo/anything-llm-icon.png";
+import OpenAiOptions from "@/components/LLMSelection/OpenAiOptions";
+import AzureAiOptions from "@/components/LLMSelection/AzureAiOptions";
+import AnthropicAiOptions from "@/components/LLMSelection/AnthropicAiOptions";
+import LMStudioOptions from "@/components/LLMSelection/LMStudioOptions";
+import LocalAiOptions from "@/components/LLMSelection/LocalAiOptions";
+import NativeLLMOptions from "@/components/LLMSelection/NativeLLMOptions";
+import GeminiLLMOptions from "@/components/LLMSelection/GeminiLLMOptions";
+import OllamaLLMOptions from "@/components/LLMSelection/OllamaLLMOptions";
+import LLMItem from "./LLMItem";
+import System from "@/models/system";
+import paths from "@/utils/paths";
+import showToast from "@/utils/toast";
+import { useNavigate } from "react-router-dom";
+
+const TITLE = "LLM Preference";
+const DESCRIPTION =
+  "AnythingLLM can work with many LLM providers. This will be the service which handles chatting.";
+
+export default function LLMPreference({
+  setHeader,
+  setForwardBtn,
+  setBackBtn,
+}) {
+  const [searchQuery, setSearchQuery] = useState("");
+  const [filteredLLMs, setFilteredLLMs] = useState([]);
+  const [selectedLLM, setSelectedLLM] = useState(null);
+  const [settings, setSettings] = useState(null);
+  const formRef = useRef(null);
+  const hiddenSubmitButtonRef = useRef(null);
+  const isHosted = window.location.hostname.includes("useanything.com");
+  const navigate = useNavigate();
+
+  useEffect(() => {
+    async function fetchKeys() {
+      const _settings = await System.keys();
+      setSettings(_settings);
+      setSelectedLLM(_settings?.LLMProvider || "openai");
+    }
+    fetchKeys();
+  }, []);
+
+  const LLMS = [
+    {
+      name: "OpenAI",
+      value: "openai",
+      logo: OpenAiLogo,
+      options: <OpenAiOptions settings={settings} />,
+      description: "The standard option for most non-commercial use.",
+    },
+    {
+      name: "Azure OpenAI",
+      value: "azure",
+      logo: AzureOpenAiLogo,
+      options: <AzureAiOptions settings={settings} />,
+      description: "The enterprise option of OpenAI hosted on Azure services.",
+    },
+    {
+      name: "Anthropic",
+      value: "anthropic",
+      logo: AnthropicLogo,
+      options: <AnthropicAiOptions settings={settings} />,
+      description: "A friendly AI Assistant hosted by Anthropic.",
+    },
+    {
+      name: "Gemini",
+      value: "gemini",
+      logo: GeminiLogo,
+      options: <GeminiLLMOptions settings={settings} />,
+      description: "Google's largest and most capable AI model",
+    },
+    {
+      name: "Ollama",
+      value: "ollama",
+      logo: OllamaLogo,
+      options: <OllamaLLMOptions settings={settings} />,
+      description: "Run LLMs locally on your own machine.",
+    },
+    {
+      name: "LM Studio",
+      value: "lmstudio",
+      logo: LMStudioLogo,
+      options: <LMStudioOptions settings={settings} />,
+      description:
+        "Discover, download, and run thousands of cutting edge LLMs in a few clicks.",
+    },
+    {
+      name: "Local AI",
+      value: "localai",
+      logo: LocalAiLogo,
+      options: <LocalAiOptions settings={settings} />,
+      description: "Run LLMs locally on your own machine.",
+    },
+    {
+      name: "Native",
+      value: "native",
+      logo: AnythingLLMIcon,
+      options: <NativeLLMOptions settings={settings} />,
+      description:
+        "Use a downloaded custom Llama model for chatting on this AnythingLLM instance.",
+    },
+  ];
+
+  function handleForward() {
+    if (hiddenSubmitButtonRef.current) {
+      hiddenSubmitButtonRef.current.click();
+    }
+  }
+
+  function handleBack() {
+    navigate(paths.onboarding.home());
+  }
+
+  const handleSubmit = async (e) => {
+    e.preventDefault();
+    const form = e.target;
+    const data = {};
+    const formData = new FormData(form);
+    data.LLMProvider = selectedLLM;
+    for (var [key, value] of formData.entries()) data[key] = value;
+
+    const { error } = await System.updateSystem(data);
+    if (error) {
+      showToast(`Failed to save LLM settings: ${error}`, "error");
+      return;
+    }
+    showToast("LLM settings saved successfully.", "success", { clear: true });
+    navigate(paths.onboarding.embeddingPreference());
+  };
+
+  useEffect(() => {
+    setHeader({ title: TITLE, description: DESCRIPTION });
+    setForwardBtn({ showing: true, disabled: false, onClick: handleForward });
+    setBackBtn({ showing: true, disabled: false, onClick: handleBack });
+  }, []);
+
+  useEffect(() => {
+    if (searchQuery.trim() === "") {
+      setFilteredLLMs(LLMS);
+    } else {
+      const lowercasedQuery = searchQuery.toLowerCase();
+      const filtered = LLMS.filter((llm) =>
+        llm.name.toLowerCase().includes(lowercasedQuery)
+      );
+      setFilteredLLMs(filtered);
+    }
+  }, [searchQuery]);
+
+  return (
+    <div>
+      <form ref={formRef} onSubmit={handleSubmit} className="w-full">
+        <div className="w-full relative border-slate-300/40 shadow border-2 rounded-lg text-white">
+          <div className="w-full p-4 absolute top-0 rounded-t-lg bg-accent/50">
+            <div className="w-full flex items-center sticky top-0 z-20">
+              <MagnifyingGlass
+                size={16}
+                weight="bold"
+                className="absolute left-4 z-30 text-white"
+              />
+              <input
+                type="text"
+                placeholder="Search LLM providers"
+                className="bg-zinc-600 z-20 pl-10 rounded-full w-full px-4 py-1 text-sm border-2 border-slate-300/40 outline-none focus:border-white text-white"
+                onChange={(e) => setSearchQuery(e.target.value)}
+                autoComplete="off"
+                onKeyDown={(e) => {
+                  if (e.key === "Enter") e.preventDefault();
+                }}
+              />
+            </div>
+          </div>
+          <div className="px-4 pt-[70px] flex flex-col gap-y-1 max-h-[390px] overflow-y-auto no-scroll pb-4">
+            {filteredLLMs.map((llm) => {
+              if (llm.value === "native" && isHosted) return null;
+              return (
+                <LLMItem
+                  key={llm.name}
+                  name={llm.name}
+                  value={llm.value}
+                  image={llm.logo}
+                  description={llm.description}
+                  checked={selectedLLM === llm.value}
+                  onClick={() => setSelectedLLM(llm.value)}
+                />
+              );
+            })}
+          </div>
+        </div>
+        <div className="mt-4 flex flex-col gap-y-1">
+          {selectedLLM &&
+            LLMS.find((llm) => llm.value === selectedLLM)?.options}
+        </div>
+        <button
+          type="submit"
+          ref={hiddenSubmitButtonRef}
+          hidden
+          aria-hidden="true"
+        ></button>
+      </form>
+    </div>
+  );
+}
diff --git a/frontend/src/pages/OnboardingFlow/Steps/Survey/index.jsx b/frontend/src/pages/OnboardingFlow/Steps/Survey/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..35b2f67d07555f1c2286ef158d4bf011261f348a
--- /dev/null
+++ b/frontend/src/pages/OnboardingFlow/Steps/Survey/index.jsx
@@ -0,0 +1,297 @@
+import { COMPLETE_QUESTIONNAIRE } from "@/utils/constants";
+import paths from "@/utils/paths";
+import { CheckCircle } from "@phosphor-icons/react";
+import React, { useState, useEffect, useRef } from "react";
+import { useNavigate } from "react-router-dom";
+
+const TITLE = "Welcome to AnythingLLM";
+const DESCRIPTION = "Help us make AnythingLLM built for your needs. Optional.";
+
+async function sendQuestionnaire({ email, useCase, comment }) {
+  if (import.meta.env.DEV) return;
+  return fetch(`https://onboarding-wxich7363q-uc.a.run.app`, {
+    method: "POST",
+    body: JSON.stringify({
+      email,
+      useCase,
+      comment,
+      sourceId: "0VRjqHh6Vukqi0x0Vd0n/m8JuT7k8nOz",
+    }),
+  })
+    .then(() => {
+      window.localStorage.setItem(COMPLETE_QUESTIONNAIRE, true);
+      console.log(`✅ Questionnaire responses sent.`);
+    })
+    .catch((error) => {
+      console.error(`sendQuestionnaire`, error.message);
+    });
+}
+
+export default function Survey({ setHeader, setForwardBtn, setBackBtn }) {
+  const [selectedOption, setSelectedOption] = useState("");
+  const formRef = useRef(null);
+  const navigate = useNavigate();
+  const submitRef = useRef(null);
+
+  function handleForward() {
+    if (!!window?.localStorage?.getItem(COMPLETE_QUESTIONNAIRE)) {
+      navigate(paths.onboarding.createWorkspace());
+      return;
+    }
+    if (submitRef.current) {
+      submitRef.current.click();
+    }
+  }
+
+  function skipSurvey() {
+    navigate(paths.onboarding.createWorkspace());
+  }
+
+  function handleBack() {
+    navigate(paths.onboarding.dataHandling());
+  }
+
+  useEffect(() => {
+    setHeader({ title: TITLE, description: DESCRIPTION });
+    setForwardBtn({ showing: true, disabled: false, onClick: handleForward });
+    setBackBtn({ showing: true, disabled: false, onClick: handleBack });
+  }, []);
+
+  const handleSubmit = async (e) => {
+    e.preventDefault();
+    const form = e.target;
+    const formData = new FormData(form);
+
+    await sendQuestionnaire({
+      email: formData.get("email"),
+      useCase: formData.get("use_case") || "other",
+      comment: formData.get("comment") || null,
+    });
+
+    navigate(paths.onboarding.createWorkspace());
+  };
+
+  if (!!window?.localStorage?.getItem(COMPLETE_QUESTIONNAIRE)) {
+    return (
+      <div className="w-full flex justify-center items-center py-40">
+        <div className="w-full flex items-center justify-center px-1 md:px-8 py-4">
+          <div className="w-auto flex flex-col gap-y-1 items-center">
+            <CheckCircle size={60} className="text-green-500" />
+            <p className="text-white text-lg">Thank you for your feedback!</p>
+            <a
+              href={paths.mailToMintplex()}
+              className="text-sky-400 underline text-xs"
+            >
+              team@mintplexlabs.com
+            </a>
+          </div>
+        </div>
+      </div>
+    );
+  }
+
+  return (
+    <div className="w-full flex justify-center">
+      <form onSubmit={handleSubmit} ref={formRef} className="">
+        <div className="md:min-w-[400px]">
+          <label htmlFor="email" className="text-white text-base font-medium">
+            What's your email?{" "}
+          </label>
+          <input
+            name="email"
+            type="email"
+            placeholder="you@gmail.com"
+            required={true}
+            className="mt-2 bg-zinc-900 text-white text-sm font-medium font-['Plus Jakarta Sans'] leading-tight w-full h-11 p-2.5 bg-zinc-900 rounded-lg"
+          />
+        </div>
+
+        <div className="mt-8">
+          <label
+            className="text-white text-base font-medium"
+            htmlFor="use_case"
+          >
+            What will you use AnythingLLM for?{" "}
+          </label>
+          <div className="mt-2 gap-y-3 flex flex-col">
+            <label
+              className={`transition-all duration-300 w-full h-11 p-2.5 bg-white/10 rounded-lg flex justify-start items-center gap-2.5 cursor-pointer border border-transparent ${
+                selectedOption === "business"
+                  ? "border-white border-opacity-40"
+                  : ""
+              } hover:border-white/60`}
+            >
+              <input
+                type="radio"
+                name="use_case"
+                value={"business"}
+                checked={selectedOption === "business"}
+                onChange={(e) => setSelectedOption(e.target.value)}
+                className="hidden"
+              />
+              <div
+                className={`w-4 h-4 rounded-full border-2 border-white mr-2 ${
+                  selectedOption === "business" ? "bg-white" : ""
+                }`}
+              ></div>
+              <div className="text-white text-sm font-medium font-['Plus Jakarta Sans'] leading-tight">
+                For my business
+              </div>
+            </label>
+            <label
+              className={`transition-all duration-300 w-full h-11 p-2.5 bg-white/10 rounded-lg flex justify-start items-center gap-2.5 cursor-pointer border border-transparent ${
+                selectedOption === "personal"
+                  ? "border-white border-opacity-40"
+                  : ""
+              } hover:border-white/60`}
+            >
+              <input
+                type="radio"
+                name="use_case"
+                value={"personal"}
+                checked={selectedOption === "personal"}
+                onChange={(e) => setSelectedOption(e.target.value)}
+                className="hidden"
+              />
+              <div
+                className={`w-4 h-4 rounded-full border-2 border-white mr-2 ${
+                  selectedOption === "personal" ? "bg-white" : ""
+                }`}
+              ></div>
+              <div className="text-white text-sm font-medium font-['Plus Jakarta Sans'] leading-tight">
+                For personal use
+              </div>
+            </label>
+            <label
+              className={`transition-all duration-300 w-full h-11 p-2.5 bg-white/10 rounded-lg flex justify-start items-center gap-2.5 cursor-pointer border border-transparent ${
+                selectedOption === "education"
+                  ? "border-white border-opacity-40"
+                  : ""
+              } hover:border-white/60`}
+            >
+              <input
+                type="radio"
+                name="use_case"
+                value={"education"}
+                checked={selectedOption === "education"}
+                onChange={(e) => setSelectedOption(e.target.value)}
+                className="hidden"
+              />
+              <div
+                className={`w-4 h-4 rounded-full border-2 border-white mr-2 ${
+                  selectedOption === "education" ? "bg-white" : ""
+                }`}
+              ></div>
+              <div className="text-white text-sm font-medium font-['Plus Jakarta Sans'] leading-tight">
+                For my education
+              </div>
+            </label>
+            <label
+              className={`transition-all duration-300 w-full h-11 p-2.5 bg-white/10 rounded-lg flex justify-start items-center gap-2.5 cursor-pointer border border-transparent ${
+                selectedOption === "side_hustle"
+                  ? "border-white border-opacity-40"
+                  : ""
+              } hover:border-white/60`}
+            >
+              <input
+                type="radio"
+                name="use_case"
+                value={"side_hustle"}
+                checked={selectedOption === "side_hustle"}
+                onChange={(e) => setSelectedOption(e.target.value)}
+                className="hidden"
+              />
+              <div
+                className={`w-4 h-4 rounded-full border-2 border-white mr-2 ${
+                  selectedOption === "side_hustle" ? "bg-white" : ""
+                }`}
+              ></div>
+              <div className="text-white text-sm font-medium font-['Plus Jakarta Sans'] leading-tight">
+                For my side-hustle
+              </div>
+            </label>
+            <label
+              className={`transition-all duration-300 w-full h-11 p-2.5 bg-white/10 rounded-lg flex justify-start items-center gap-2.5 cursor-pointer border border-transparent ${
+                selectedOption === "job" ? "border-white border-opacity-40" : ""
+              } hover:border-white/60`}
+            >
+              <input
+                type="radio"
+                name="use_case"
+                value={"job"}
+                checked={selectedOption === "job"}
+                onChange={(e) => setSelectedOption(e.target.value)}
+                className="hidden"
+              />
+              <div
+                className={`w-4 h-4 rounded-full border-2 border-white mr-2 ${
+                  selectedOption === "job" ? "bg-white" : ""
+                }`}
+              ></div>
+              <div className="text-white text-sm font-medium font-['Plus Jakarta Sans'] leading-tight">
+                For my job
+              </div>
+            </label>
+            <label
+              className={`transition-all duration-300 w-full h-11 p-2.5 bg-white/10 rounded-lg flex justify-start items-center gap-2.5 cursor-pointer border border-transparent ${
+                selectedOption === "other"
+                  ? "border-white border-opacity-40"
+                  : ""
+              } hover:border-white/60`}
+            >
+              <input
+                type="radio"
+                name="use_case"
+                value={"other"}
+                checked={selectedOption === "other"}
+                onChange={(e) => setSelectedOption(e.target.value)}
+                className="hidden"
+              />
+              <div
+                className={`w-4 h-4 rounded-full border-2 border-white mr-2 ${
+                  selectedOption === "other" ? "bg-white" : ""
+                }`}
+              ></div>
+              <div className="text-white text-sm font-medium font-['Plus Jakarta Sans'] leading-tight">
+                Other
+              </div>
+            </label>
+          </div>
+        </div>
+
+        <div className="mt-8">
+          <label htmlFor="comment" className="text-white text-base font-medium">
+            Any comments for the team?{" "}
+            <span className="text-neutral-400 text-base font-light">
+              (Optional)
+            </span>
+          </label>
+          <textarea
+            name="comment"
+            rows={5}
+            className="mt-2 bg-zinc-900 text-white text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
+            placeholder="If you have any questions or comments right now, you can leave them here and we will get back to you. You can also email team@mintplexlabs.com"
+            wrap="soft"
+            autoComplete="off"
+          />
+        </div>
+        <button
+          type="submit"
+          ref={submitRef}
+          hidden
+          aria-hidden="true"
+        ></button>
+
+        <div className="w-full flex items-center justify-center">
+          <button
+            type="button"
+            onClick={skipSurvey}
+            className="text-white text-base font-medium text-opacity-30 hover:text-opacity-100 mt-8"
+          >
+            Skip Survey
+          </button>
+        </div>
+      </form>
+    </div>
+  );
+}
diff --git a/frontend/src/pages/OnboardingFlow/Steps/UserSetup/index.jsx b/frontend/src/pages/OnboardingFlow/Steps/UserSetup/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..500a483a18c6cfa738db53e406d28ce17ac4c427
--- /dev/null
+++ b/frontend/src/pages/OnboardingFlow/Steps/UserSetup/index.jsx
@@ -0,0 +1,336 @@
+import System from "@/models/system";
+import showToast from "@/utils/toast";
+import React, { useState, useEffect, useRef } from "react";
+import debounce from "lodash.debounce";
+import paths from "@/utils/paths";
+import { useNavigate } from "react-router-dom";
+import { AUTH_TIMESTAMP, AUTH_TOKEN, AUTH_USER } from "@/utils/constants";
+
+const TITLE = "User Setup";
+const DESCRIPTION = "Configure your user settings.";
+
+export default function UserSetup({ setHeader, setForwardBtn, setBackBtn }) {
+  const [selectedOption, setSelectedOption] = useState("");
+  const [singleUserPasswordValid, setSingleUserPasswordValid] = useState(false);
+  const [multiUserLoginValid, setMultiUserLoginValid] = useState(false);
+  const [enablePassword, setEnablePassword] = useState(false);
+  const myTeamSubmitRef = useRef(null);
+  const justMeSubmitRef = useRef(null);
+  const navigate = useNavigate();
+
+  function handleForward() {
+    if (selectedOption === "just_me" && enablePassword) {
+      justMeSubmitRef.current?.click();
+    } else if (selectedOption === "just_me" && !enablePassword) {
+      navigate(paths.onboarding.dataHandling());
+    } else if (selectedOption === "my_team") {
+      myTeamSubmitRef.current?.click();
+    }
+  }
+
+  function handleBack() {
+    navigate(paths.onboarding.customLogo());
+  }
+
+  useEffect(() => {
+    let isDisabled = true;
+    if (selectedOption === "just_me") {
+      isDisabled = !singleUserPasswordValid;
+    } else if (selectedOption === "my_team") {
+      isDisabled = !multiUserLoginValid;
+    }
+
+    setForwardBtn({
+      showing: true,
+      disabled: isDisabled,
+      onClick: handleForward,
+    });
+  }, [selectedOption, singleUserPasswordValid, multiUserLoginValid]);
+
+  useEffect(() => {
+    setHeader({ title: TITLE, description: DESCRIPTION });
+    setBackBtn({ showing: true, disabled: false, onClick: handleBack });
+  }, []);
+
+  return (
+    <div className="w-full flex items-center justify-center flex-col gap-y-6">
+      <div className="flex flex-col border rounded-lg border-white/20 p-8 items-center gap-y-4 w-full max-w-[600px]">
+        <div className=" text-white text-sm font-semibold md:-ml-44">
+          How many people will be using your instance?
+        </div>
+        <div className="flex flex-col md:flex-row gap-6 w-full justify-center">
+          <button
+            onClick={() => setSelectedOption("just_me")}
+            className={`${
+              selectedOption === "just_me"
+                ? "text-sky-400 border-sky-400/70"
+                : "text-white border-white/40"
+            } min-w-[230px] h-11 p-4 rounded-[10px] border-2  justify-center items-center gap-[100px] inline-flex hover:border-sky-400/70 hover:text-sky-400 transition-all duration-300`}
+          >
+            <div className="text-center text-sm font-bold">Just me</div>
+          </button>
+          <button
+            onClick={() => setSelectedOption("my_team")}
+            className={`${
+              selectedOption === "my_team"
+                ? "text-sky-400 border-sky-400/70"
+                : "text-white border-white/40"
+            } min-w-[230px] h-11 p-4 rounded-[10px] border-2  justify-center items-center gap-[100px] inline-flex hover:border-sky-400/70 hover:text-sky-400 transition-all duration-300`}
+          >
+            <div className="text-center text-sm font-bold">My team</div>
+          </button>
+        </div>
+      </div>
+      {selectedOption === "just_me" && (
+        <JustMe
+          setSingleUserPasswordValid={setSingleUserPasswordValid}
+          enablePassword={enablePassword}
+          setEnablePassword={setEnablePassword}
+          justMeSubmitRef={justMeSubmitRef}
+          navigate={navigate}
+        />
+      )}
+      {selectedOption === "my_team" && (
+        <MyTeam
+          setMultiUserLoginValid={setMultiUserLoginValid}
+          myTeamSubmitRef={myTeamSubmitRef}
+          navigate={navigate}
+        />
+      )}
+    </div>
+  );
+}
+
+const JustMe = ({
+  setSingleUserPasswordValid,
+  enablePassword,
+  setEnablePassword,
+  justMeSubmitRef,
+  navigate,
+}) => {
+  const [itemSelected, setItemSelected] = useState(false);
+  const [password, setPassword] = useState("");
+  const handleSubmit = async (e) => {
+    e.preventDefault();
+    const form = e.target;
+    const formData = new FormData(form);
+    const { error } = await System.updateSystemPassword({
+      usePassword: true,
+      newPassword: formData.get("password"),
+    });
+
+    if (error) {
+      showToast(`Failed to set password: ${error}`, "error");
+      return;
+    }
+
+    showToast("Password set successfully!", "success", { clear: true });
+
+    // Auto-request token with password that was just set so they
+    // are not redirected to login after completion.
+    const { token } = await System.requestToken({
+      password: formData.get("password"),
+    });
+    window.localStorage.removeItem(AUTH_USER);
+    window.localStorage.removeItem(AUTH_TIMESTAMP);
+    window.localStorage.setItem(AUTH_TOKEN, token);
+
+    navigate(paths.onboarding.dataHandling());
+  };
+
+  const setNewPassword = (e) => setPassword(e.target.value);
+  const handlePasswordChange = debounce(setNewPassword, 500);
+
+  function handleYes() {
+    setItemSelected(true);
+    setEnablePassword(true);
+  }
+
+  function handleNo() {
+    setItemSelected(true);
+    setEnablePassword(false);
+  }
+
+  useEffect(() => {
+    if (enablePassword && itemSelected && password.length >= 8) {
+      setSingleUserPasswordValid(true);
+    } else if (!enablePassword && itemSelected) {
+      setSingleUserPasswordValid(true);
+    } else {
+      setSingleUserPasswordValid(false);
+    }
+  });
+  return (
+    <div className="w-full flex items-center justify-center flex-col gap-y-6">
+      <div className="flex flex-col border rounded-lg border-white/20 p-8 items-center gap-y-4 w-full max-w-[600px]">
+        <div className=" text-white text-sm font-semibold md:-ml-56">
+          Would you like to set up a password?
+        </div>
+        <div className="flex flex-col md:flex-row gap-6 w-full justify-center">
+          <button
+            onClick={handleYes}
+            className={`${
+              enablePassword && itemSelected
+                ? "text-sky-400 border-sky-400/70"
+                : "text-white border-white/40"
+            } min-w-[230px] h-11 p-4 rounded-[10px] border-2  justify-center items-center gap-[100px] inline-flex hover:border-sky-400/70 hover:text-sky-400 transition-all duration-300`}
+          >
+            <div className="text-center text-sm font-bold">Yes</div>
+          </button>
+          <button
+            onClick={handleNo}
+            className={`${
+              !enablePassword && itemSelected
+                ? "text-sky-400 border-sky-400/70"
+                : "text-white border-white/40"
+            } min-w-[230px] h-11 p-4 rounded-[10px] border-2  justify-center items-center gap-[100px] inline-flex hover:border-sky-400/70 hover:text-sky-400 transition-all duration-300`}
+          >
+            <div className="text-center text-sm font-bold">No</div>
+          </button>
+        </div>
+        {enablePassword && (
+          <form className="w-full mt-4" onSubmit={handleSubmit}>
+            <label
+              htmlFor="name"
+              className="block mb-3 text-sm font-medium text-white"
+            >
+              Instance Password
+            </label>
+            <input
+              name="password"
+              type="password"
+              className="bg-zinc-900 text-white text-sm rounded-lg block w-full p-2.5"
+              placeholder="Your admin password"
+              minLength={6}
+              required={true}
+              autoComplete="off"
+              onChange={handlePasswordChange}
+            />
+            <div className="mt-4 text-white text-opacity-80 text-xs font-base -mb-2">
+              Passwords must be at least 8 characters.
+              <br />
+              <i>
+                It's important to save this password because there is no
+                recovery method.
+              </i>{" "}
+            </div>
+            <button
+              type="submit"
+              ref={justMeSubmitRef}
+              hidden
+              aria-hidden="true"
+            ></button>
+          </form>
+        )}
+      </div>
+    </div>
+  );
+};
+
+const MyTeam = ({ setMultiUserLoginValid, myTeamSubmitRef, navigate }) => {
+  const [username, setUsername] = useState("");
+  const [password, setPassword] = useState("");
+
+  const handleSubmit = async (e) => {
+    e.preventDefault();
+    const form = e.target;
+    const formData = new FormData(form);
+    const data = {
+      username: formData.get("username"),
+      password: formData.get("password"),
+    };
+    const { success, error } = await System.setupMultiUser(data);
+    if (!success) {
+      showToast(`Error: ${error}`, "error");
+      return;
+    }
+
+    showToast("Multi-user login enabled.", "success", { clear: true });
+    navigate(paths.onboarding.dataHandling());
+
+    // Auto-request token with credentials that was just set so they
+    // are not redirected to login after completion.
+    const { user, token } = await System.requestToken(data);
+    window.localStorage.setItem(AUTH_USER, JSON.stringify(user));
+    window.localStorage.setItem(AUTH_TOKEN, token);
+    window.localStorage.removeItem(AUTH_TIMESTAMP);
+  };
+
+  const setNewUsername = (e) => setUsername(e.target.value);
+  const setNewPassword = (e) => setPassword(e.target.value);
+  const handleUsernameChange = debounce(setNewUsername, 500);
+  const handlePasswordChange = debounce(setNewPassword, 500);
+
+  useEffect(() => {
+    if (username.length >= 6 && password.length >= 8) {
+      setMultiUserLoginValid(true);
+    } else {
+      setMultiUserLoginValid(false);
+    }
+  }, [username, password]);
+  return (
+    <div className="w-full flex items-center justify-center border max-w-[600px] rounded-lg border-white/20">
+      <form onSubmit={handleSubmit}>
+        <div className="flex flex-col w-full md:px-8 px-2 py-4">
+          <div className="space-y-6 flex h-full w-full">
+            <div className="w-full flex flex-col gap-y-4">
+              <div>
+                <label
+                  htmlFor="name"
+                  className="block mb-3 text-sm font-medium text-white"
+                >
+                  Admin account username
+                </label>
+                <input
+                  name="username"
+                  type="text"
+                  className="bg-zinc-900 text-white text-sm rounded-lg block w-full p-2.5"
+                  placeholder="Your admin username"
+                  minLength={6}
+                  required={true}
+                  autoComplete="off"
+                  onChange={handleUsernameChange}
+                />
+              </div>
+              <div className="mt-4">
+                <label
+                  htmlFor="name"
+                  className="block mb-3 text-sm font-medium text-white"
+                >
+                  Admin account password
+                </label>
+                <input
+                  name="password"
+                  type="password"
+                  className="bg-zinc-900 text-white text-sm rounded-lg block w-full p-2.5"
+                  placeholder="Your admin password"
+                  minLength={8}
+                  required={true}
+                  autoComplete="off"
+                  onChange={handlePasswordChange}
+                />
+              </div>
+              <p className="w-96 text-white text-opacity-80 text-xs font-base">
+                Username must be at least 6 characters long. Password must be at
+                least 8 characters long.
+              </p>
+            </div>
+          </div>
+        </div>
+        <div className="flex w-full justify-between items-center px-6 py-4 space-x-6 border-t rounded-b border-gray-500/50">
+          <div className=" text-white text-opacity-80 text-xs font-base">
+            By default, you will be the only admin. Once onboarding is completed
+            you can create and invite others to be users or admins. Do not lose
+            your password as only admins can reset passwords.
+          </div>
+        </div>
+        <button
+          type="submit"
+          ref={myTeamSubmitRef}
+          hidden
+          aria-hidden="true"
+        ></button>
+      </form>
+    </div>
+  );
+};
diff --git a/frontend/src/pages/OnboardingFlow/Steps/VectorDatabaseConnection/VectorDatabaseItem.jsx b/frontend/src/pages/OnboardingFlow/Steps/VectorDatabaseConnection/VectorDatabaseItem.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..4ecd304f7a1280b1762b9a8f791c37153cbb9d0a
--- /dev/null
+++ b/frontend/src/pages/OnboardingFlow/Steps/VectorDatabaseConnection/VectorDatabaseItem.jsx
@@ -0,0 +1,37 @@
+export default function VectorDatabaseItem({
+  name,
+  value,
+  image,
+  description,
+  checked,
+  onClick,
+}) {
+  return (
+    <div
+      onClick={() => onClick(value)}
+      className={`w-full hover:bg-white/10 p-2 rounded-md hover:cursor-pointer ${
+        checked ? "bg-white/10" : ""
+      }`}
+    >
+      <input
+        type="checkbox"
+        value={value}
+        className="peer hidden"
+        checked={checked}
+        readOnly={true}
+        formNoValidate={true}
+      />
+      <div className="flex gap-x-4 items-center">
+        <img
+          src={image}
+          alt={`${name} logo`}
+          className="w-10 h-10 rounded-md"
+        />
+        <div className="flex flex-col gap-y-1">
+          <div className="text-sm font-semibold">{name}</div>
+          <div className="text-xs text-white tracking-wide">{description}</div>
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git a/frontend/src/pages/OnboardingFlow/Steps/VectorDatabaseConnection/index.jsx b/frontend/src/pages/OnboardingFlow/Steps/VectorDatabaseConnection/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..17accbab0080a3adf69246ec168671cb7a7183e2
--- /dev/null
+++ b/frontend/src/pages/OnboardingFlow/Steps/VectorDatabaseConnection/index.jsx
@@ -0,0 +1,182 @@
+import React, { useEffect, useState, useRef } from "react";
+import { MagnifyingGlass } from "@phosphor-icons/react";
+import ChromaLogo from "@/media/vectordbs/chroma.png";
+import PineconeLogo from "@/media/vectordbs/pinecone.png";
+import LanceDbLogo from "@/media/vectordbs/lancedb.png";
+import WeaviateLogo from "@/media/vectordbs/weaviate.png";
+import QDrantLogo from "@/media/vectordbs/qdrant.png";
+import System from "@/models/system";
+import VectorDatabaseItem from "./VectorDatabaseItem";
+import paths from "@/utils/paths";
+import PineconeDBOptions from "@/components/VectorDBSelection/PineconeDBOptions";
+import ChromaDBOptions from "@/components/VectorDBSelection/ChromaDBOptions";
+import QDrantDBOptions from "@/components/VectorDBSelection/QDrantDBOptions";
+import WeaviateDBOptions from "@/components/VectorDBSelection/WeaviateDBOptions";
+import LanceDBOptions from "@/components/VectorDBSelection/LanceDBOptions";
+import showToast from "@/utils/toast";
+import { useNavigate } from "react-router-dom";
+
+const TITLE = "Vector Database Connection";
+const DESCRIPTION =
+  "These are the credentials and settings for your vector database of choice.";
+
+export default function VectorDatabaseConnection({
+  setHeader,
+  setForwardBtn,
+  setBackBtn,
+}) {
+  const [searchQuery, setSearchQuery] = useState("");
+  const [filteredVDBs, setFilteredVDBs] = useState([]);
+  const [selectedVDB, setSelectedVDB] = useState(null);
+  const [settings, setSettings] = useState(null);
+  const formRef = useRef(null);
+  const hiddenSubmitButtonRef = useRef(null);
+  const navigate = useNavigate();
+
+  useEffect(() => {
+    async function fetchKeys() {
+      const _settings = await System.keys();
+      setSettings(_settings);
+      setSelectedVDB(_settings?.VectorDB || "lancedb");
+    }
+    fetchKeys();
+  }, []);
+
+  const VECTOR_DBS = [
+    {
+      name: "LanceDB",
+      value: "lancedb",
+      logo: LanceDbLogo,
+      options: <LanceDBOptions />,
+      description:
+        "100% local vector DB that runs on the same instance as AnythingLLM.",
+    },
+    {
+      name: "Chroma",
+      value: "chroma",
+      logo: ChromaLogo,
+      options: <ChromaDBOptions settings={settings} />,
+      description:
+        "Open source vector database you can host yourself or on the cloud.",
+    },
+    {
+      name: "Pinecone",
+      value: "pinecone",
+      logo: PineconeLogo,
+      options: <PineconeDBOptions settings={settings} />,
+      description: "100% cloud-based vector database for enterprise use cases.",
+    },
+    {
+      name: "QDrant",
+      value: "qdrant",
+      logo: QDrantLogo,
+      options: <QDrantDBOptions settings={settings} />,
+      description: "Open source local and distributed cloud vector database.",
+    },
+    {
+      name: "Weaviate",
+      value: "weaviate",
+      logo: WeaviateLogo,
+      options: <WeaviateDBOptions settings={settings} />,
+      description:
+        "Open source local and cloud hosted multi-modal vector database.",
+    },
+  ];
+
+  function handleForward() {
+    if (hiddenSubmitButtonRef.current) {
+      hiddenSubmitButtonRef.current.click();
+    }
+  }
+
+  function handleBack() {
+    navigate(paths.onboarding.embeddingPreference());
+  }
+
+  const handleSubmit = async (e) => {
+    e.preventDefault();
+    const form = e.target;
+    const data = {};
+    const formData = new FormData(form);
+    data.VectorDB = selectedVDB;
+    for (var [key, value] of formData.entries()) data[key] = value;
+    const { error } = await System.updateSystem(data);
+    if (error) {
+      showToast(`Failed to save Vector Database settings: ${error}`, "error");
+      return;
+    }
+    showToast("Vector Database settings saved successfully.", "success", {
+      clear: true,
+    });
+    navigate(paths.onboarding.customLogo());
+  };
+
+  useEffect(() => {
+    setHeader({ title: TITLE, description: DESCRIPTION });
+    setForwardBtn({ showing: true, disabled: false, onClick: handleForward });
+    setBackBtn({ showing: true, disabled: false, onClick: handleBack });
+  }, []);
+
+  useEffect(() => {
+    if (searchQuery.trim() === "") {
+      setFilteredVDBs(VECTOR_DBS);
+    } else {
+      const lowercasedQuery = searchQuery.toLowerCase();
+      const filtered = VECTOR_DBS.filter((vdb) =>
+        vdb.name.toLowerCase().includes(lowercasedQuery)
+      );
+      setFilteredVDBs(filtered);
+    }
+  }, [searchQuery]);
+
+  return (
+    <>
+      <form ref={formRef} onSubmit={handleSubmit} className="w-full">
+        <div className="w-full relative border-slate-300/40 shadow border-2 rounded-lg text-white pb-4">
+          <div className="w-full p-4 absolute top-0 rounded-t-lg bg-accent/50">
+            <div className="w-full flex items-center sticky top-0 z-20">
+              <MagnifyingGlass
+                size={16}
+                weight="bold"
+                className="absolute left-4 z-30 text-white"
+              />
+              <input
+                type="text"
+                placeholder="Search vector databases"
+                className="bg-zinc-600 z-20 pl-10 rounded-full w-full px-4 py-1 text-sm border-2 border-slate-300/40 outline-none focus:border-white text-white"
+                onChange={(e) => setSearchQuery(e.target.value)}
+                autoComplete="off"
+                onKeyDown={(e) => {
+                  if (e.key === "Enter") e.preventDefault();
+                }}
+              />
+            </div>
+          </div>
+          <div className="px-4 pt-[70px] flex flex-col gap-y-1 max-h-[390px] overflow-y-auto no-scroll">
+            {filteredVDBs.map((vdb) => (
+              <VectorDatabaseItem
+                key={vdb.name}
+                name={vdb.name}
+                value={vdb.value}
+                image={vdb.logo}
+                description={vdb.description}
+                checked={selectedVDB === vdb.value}
+                onClick={setSelectedVDB}
+              />
+            ))}
+          </div>
+        </div>
+        <div className="mt-4 flex flex-col gap-y-1">
+          {selectedVDB &&
+            VECTOR_DBS.find((vdb) => vdb.value === selectedVDB)?.options}
+        </div>
+        <button
+          type="submit"
+          ref={hiddenSubmitButtonRef}
+          hidden
+          aria-hidden="true"
+        ></button>
+      </form>
+    </>
+  );
+}
diff --git a/frontend/src/pages/OnboardingFlow/Steps/index.jsx b/frontend/src/pages/OnboardingFlow/Steps/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..3f218d531b6ed318c6364162b4b14604547cbef8
--- /dev/null
+++ b/frontend/src/pages/OnboardingFlow/Steps/index.jsx
@@ -0,0 +1,130 @@
+import { ArrowLeft, ArrowRight } from "@phosphor-icons/react";
+import { lazy, useState } from "react";
+import { isMobile } from "react-device-detect";
+const OnboardingSteps = {
+  home: lazy(() => import("./Home")),
+  "llm-preference": lazy(() => import("./LLMPreference")),
+  "embedding-preference": lazy(() => import("./EmbeddingPreference")),
+  "vector-database": lazy(() => import("./VectorDatabaseConnection")),
+  "custom-logo": lazy(() => import("./CustomLogo")),
+  "user-setup": lazy(() => import("./UserSetup")),
+  "data-handling": lazy(() => import("./DataHandling")),
+  survey: lazy(() => import("./Survey")),
+  "create-workspace": lazy(() => import("./CreateWorkspace")),
+};
+
+export default OnboardingSteps;
+
+export function OnboardingLayout({ children }) {
+  const [header, setHeader] = useState({
+    title: "",
+    description: "",
+  });
+  const [backBtn, setBackBtn] = useState({
+    showing: false,
+    disabled: true,
+    onClick: () => null,
+  });
+  const [forwardBtn, setForwardBtn] = useState({
+    showing: false,
+    disabled: true,
+    onClick: () => null,
+  });
+
+  if (isMobile) {
+    return (
+      <div className="w-screen h-screen overflow-y-auto bg-[#2C2F35] overflow-hidden">
+        <div className="flex flex-col">
+          <div className="w-full relative py-10 px-2">
+            <div className="flex flex-col w-fit mx-auto gap-y-1 mb-[55px]">
+              <h1 className="text-white font-semibold text-center text-2xl">
+                {header.title}
+              </h1>
+              <p className="text-zinc-400 text-base text-center">
+                {header.description}
+              </p>
+            </div>
+            {children(setHeader, setBackBtn, setForwardBtn)}
+          </div>
+          <div className="flex w-full justify-center gap-x-4 pb-20">
+            <div className="flex justify-center items-center">
+              {backBtn.showing && (
+                <button
+                  disabled={backBtn.disabled}
+                  onClick={backBtn.onClick}
+                  className="group p-2 rounded-lg border-2 border-zinc-300 disabled:border-zinc-600 h-fit w-fit disabled:not-allowed hover:bg-zinc-100 disabled:hover:bg-transparent"
+                >
+                  <ArrowLeft
+                    className="text-white group-hover:text-black group-disabled:text-gray-500"
+                    size={30}
+                  />
+                </button>
+              )}
+            </div>
+
+            <div className="flex justify-center items-center">
+              {forwardBtn.showing && (
+                <button
+                  disabled={forwardBtn.disabled}
+                  onClick={forwardBtn.onClick}
+                  className="group p-2 rounded-lg border-2 border-zinc-300 disabled:border-zinc-600 h-fit w-fit disabled:not-allowed hover:bg-zinc-100 disabled:hover:bg-transparent"
+                >
+                  <ArrowRight
+                    className="text-white group-hover:text-black group-disabled:text-gray-500"
+                    size={30}
+                  />
+                </button>
+              )}
+            </div>
+          </div>
+        </div>
+      </div>
+    );
+  }
+
+  return (
+    <div className="w-screen overflow-y-auto bg-[#2C2F35] md:bg-main-gradient flex justify-center overflow-hidden">
+      <div className="flex w-1/5 h-screen justify-center items-center">
+        {backBtn.showing && (
+          <button
+            disabled={backBtn.disabled}
+            onClick={backBtn.onClick}
+            className="group p-2 rounded-lg border-2 border-zinc-300 disabled:border-zinc-600 h-fit w-fit disabled:not-allowed hover:bg-zinc-100 disabled:hover:bg-transparent"
+          >
+            <ArrowLeft
+              className="text-white group-hover:text-black group-disabled:text-gray-500"
+              size={30}
+            />
+          </button>
+        )}
+      </div>
+
+      <div className="w-full md:w-3/5 relative h-full py-10">
+        <div className="flex flex-col w-fit mx-auto gap-y-1 mb-[55px]">
+          <h1 className="text-white font-semibold text-center text-2xl">
+            {header.title}
+          </h1>
+          <p className="text-zinc-400 text-base text-center">
+            {header.description}
+          </p>
+        </div>
+        {children(setHeader, setBackBtn, setForwardBtn)}
+      </div>
+
+      <div className="flex w-1/5 h-screen justify-center items-center">
+        {forwardBtn.showing && (
+          <button
+            disabled={forwardBtn.disabled}
+            onClick={forwardBtn.onClick}
+            className="group p-2 rounded-lg border-2 border-zinc-300 disabled:border-zinc-600 h-fit w-fit disabled:not-allowed hover:bg-zinc-100 disabled:hover:bg-transparent"
+          >
+            <ArrowRight
+              className="text-white group-hover:text-black group-disabled:text-gray-500"
+              size={30}
+            />
+          </button>
+        )}
+      </div>
+    </div>
+  );
+}
diff --git a/frontend/src/pages/OnboardingFlow/index.jsx b/frontend/src/pages/OnboardingFlow/index.jsx
index 106f7cbae1f5d2d6b596a40748b63a6861693c90..c46b3c0bc908cafa90b3a884aa9d943d2098e7dd 100644
--- a/frontend/src/pages/OnboardingFlow/index.jsx
+++ b/frontend/src/pages/OnboardingFlow/index.jsx
@@ -1,57 +1,21 @@
-import React, { useEffect, useState } from "react";
-import OnboardingModal, { OnboardingModalId } from "./OnboardingModal";
-import useLogo from "@/hooks/useLogo";
-import { isMobile } from "react-device-detect";
+import React from "react";
+import OnboardingSteps, { OnboardingLayout } from "./Steps";
+import { useParams } from "react-router-dom";
 
 export default function OnboardingFlow() {
-  const { logo } = useLogo();
-  const [modalVisible, setModalVisible] = useState(false);
-
-  useEffect(() => {
-    if (modalVisible) {
-      document.getElementById(OnboardingModalId)?.showModal();
-    }
-  }, [modalVisible]);
-
-  function showModal() {
-    setModalVisible(true);
-  }
-
-  if (isMobile) {
-    return (
-      <div className="w-screen h-full bg-sidebar flex items-center justify-center">
-        <div className="w-fit p-20 py-24 border-2 border-slate-300/10 rounded-2xl bg-main-gradient shadow-lg">
-          <div className="text-white text-2xl font-base text-center">
-            Welcome to
-          </div>
-          <img src={logo} alt="logo" className="w-80 mx-auto m-3 mb-11" />
-          <div className="flex justify-center items-center">
-            <p className="text-white text-sm italic text-center">
-              Please use a desktop browser to continue onboarding.
-            </p>
-          </div>
-        </div>
-      </div>
-    );
-  }
+  const { step } = useParams();
+  const StepPage = OnboardingSteps[step || "home"];
+  if (step === "home" || !step) return <StepPage />;
 
   return (
-    <div className="w-screen h-full bg-sidebar flex items-center justify-center">
-      <div className="w-fit p-20 py-24 border-2 border-slate-300/10 rounded-2xl bg-main-gradient shadow-lg">
-        <div className="text-white text-2xl font-base text-center">
-          Welcome to
-        </div>
-        <img src={logo} alt="logo" className="w-80 mx-auto m-3 mb-11" />
-        <div className="flex justify-center items-center">
-          <button
-            className="border border-slate-200 px-5 py-2.5 rounded-lg text-slate-800 bg-slate-200 text-sm items-center flex gap-x-2 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow animate-pulse"
-            onClick={showModal}
-          >
-            Get Started
-          </button>
-        </div>
-      </div>
-      {modalVisible && <OnboardingModal setModalVisible={setModalVisible} />}
-    </div>
+    <OnboardingLayout>
+      {(setHeader, setBackBtn, setForwardBtn) => (
+        <StepPage
+          setHeader={setHeader}
+          setBackBtn={setBackBtn}
+          setForwardBtn={setForwardBtn}
+        />
+      )}
+    </OnboardingLayout>
   );
 }
diff --git a/frontend/src/utils/paths.js b/frontend/src/utils/paths.js
index 7a0c7bb70cdf4fb48bb8668be0e639a5ba0f96dd..547a3b3f31b8950ac3a342235d08499f7681e2f2 100644
--- a/frontend/src/utils/paths.js
+++ b/frontend/src/utils/paths.js
@@ -7,8 +7,34 @@ export default {
   login: () => {
     return "/login";
   },
-  onboarding: () => {
-    return "/onboarding";
+  onboarding: {
+    home: () => {
+      return "/onboarding";
+    },
+    survey: () => {
+      return "/onboarding/survey";
+    },
+    llmPreference: () => {
+      return "/onboarding/llm-preference";
+    },
+    embeddingPreference: () => {
+      return "/onboarding/embedding-preference";
+    },
+    vectorDatabase: () => {
+      return "/onboarding/vector-database";
+    },
+    customLogo: () => {
+      return "/onboarding/custom-logo";
+    },
+    userSetup: () => {
+      return "/onboarding/user-setup";
+    },
+    dataHandling: () => {
+      return "/onboarding/data-handling";
+    },
+    createWorkspace: () => {
+      return "/onboarding/create-workspace";
+    },
   },
   github: () => {
     return "https://github.com/Mintplex-Labs/anything-llm";
diff --git a/server/prisma/seed.js b/server/prisma/seed.js
index 71d1e63d6829ab2085a39d6a6d4cfb46ccdf5f02..829b812ab4eb02d8fb2ca80e3c992cb55ae16b3a 100644
--- a/server/prisma/seed.js
+++ b/server/prisma/seed.js
@@ -1,12 +1,13 @@
-const { PrismaClient } = require('@prisma/client');
+const { PrismaClient } = require("@prisma/client");
 const prisma = new PrismaClient();
 
 async function main() {
   const settings = [
-    { label: 'multi_user_mode', value: 'false' },
-    { label: 'users_can_delete_workspaces', value: 'false' },
-    { label: 'limit_user_messages', value: 'false' },
-    { label: 'message_limit', value: '25' },
+    { label: "multi_user_mode", value: "false" },
+    { label: "users_can_delete_workspaces", value: "false" },
+    { label: "limit_user_messages", value: "false" },
+    { label: "message_limit", value: "25" },
+    { label: "logo_filename", value: "anything-llm.png" },
   ];
 
   for (let setting of settings) {
@@ -24,7 +25,7 @@ async function main() {
 }
 
 main()
-  .catch(e => {
+  .catch((e) => {
     console.error(e);
     process.exit(1);
   })