diff --git a/templates/components/ui/html/chat/use-config.ts b/templates/components/ui/html/chat/hooks/use-config.ts
similarity index 100%
rename from templates/components/ui/html/chat/use-config.ts
rename to templates/components/ui/html/chat/hooks/use-config.ts
diff --git a/templates/types/streaming/express/package.json b/templates/types/streaming/express/package.json
index b77c2e438fb624234ec98b2af88997c0cdb345d3..667ecc47ef53862c2b6393f343c52d437fef1100 100644
--- a/templates/types/streaming/express/package.json
+++ b/templates/types/streaming/express/package.json
@@ -7,7 +7,7 @@
     "format:write": "prettier --ignore-unknown --write .",
     "build": "tsup index.ts --format cjs --dts",
     "start": "node dist/index.js",
-    "dev": "concurrently \"tsup index.ts --format cjs --dts --watch\" \"nodemon -q dist/index.js\""
+    "dev": "concurrently \"tsup index.ts --format cjs --dts --watch\" \"nodemon --watch dist/index.js\""
   },
   "dependencies": {
     "ai": "^3.0.21",
diff --git a/templates/types/streaming/nextjs/app/components/chat-section.tsx b/templates/types/streaming/nextjs/app/components/chat-section.tsx
index 9a4ea6b9e73924ad2e0c8045dd1d18ab02e1c7b2..5703660eebb09ae0b347f394eecc9d02d5893dd4 100644
--- a/templates/types/streaming/nextjs/app/components/chat-section.tsx
+++ b/templates/types/streaming/nextjs/app/components/chat-section.tsx
@@ -2,7 +2,7 @@
 
 import { useChat } from "ai/react";
 import { ChatInput, ChatMessages } from "./ui/chat";
-import { useClientConfig } from "./ui/chat/use-config";
+import { useClientConfig } from "./ui/chat/hooks/use-config";
 
 export default function ChatSection() {
   const { chatAPI } = useClientConfig();
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-input.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-input.tsx
index 8ee4ec3740d0ec089abf9fd592da3449542ee30e..8a377b494b80a7f9d2f414ea22d8009af4186052 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-input.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-input.tsx
@@ -8,7 +8,7 @@ import { Input } from "../input";
 import UploadCsvPreview from "../upload-csv-preview";
 import UploadImagePreview from "../upload-image-preview";
 import { ChatHandler } from "./chat.interface";
-import { useCsv } from "./use-csv";
+import { useCsv } from "./hooks/use-csv";
 
 export default function ChatInput(
   props: Pick<
@@ -81,23 +81,27 @@ export default function ChatInput(
 
   const onRemovePreviewImage = () => setImageUrl(null);
 
-  const handleUploadImageFile = async (file: File) => {
-    const base64 = await new Promise<string>((resolve, reject) => {
+  const readContent = async (file: File): Promise<string> => {
+    const content = await new Promise<string>((resolve, reject) => {
       const reader = new FileReader();
-      reader.readAsDataURL(file);
+      if (file.type.startsWith("image/")) {
+        reader.readAsDataURL(file);
+      } else {
+        reader.readAsText(file);
+      }
       reader.onload = () => resolve(reader.result as string);
       reader.onerror = (error) => reject(error);
     });
+    return content;
+  };
+
+  const handleUploadImageFile = async (file: File) => {
+    const base64 = await readContent(file);
     setImageUrl(base64);
   };
 
   const handleUploadCsvFile = async (file: File) => {
-    const content = await new Promise<string>((resolve, reject) => {
-      const reader = new FileReader();
-      reader.readAsText(file);
-      reader.onload = () => resolve(reader.result as string);
-      reader.onerror = (error) => reject(error);
-    });
+    const content = await readContent(file);
     const isSuccess = upload({
       id: uuidv4(),
       content,
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-avatar.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-avatar.tsx
similarity index 100%
rename from templates/types/streaming/nextjs/app/components/ui/chat/chat-avatar.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-avatar.tsx
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-events.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-events.tsx
similarity index 92%
rename from templates/types/streaming/nextjs/app/components/ui/chat/chat-events.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-events.tsx
index af306768bd79f40e1d6dfd93433927a0cf54755b..3dfad75d23e03b3824e4acde6f6953cf9a3a28c1 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-events.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-events.tsx
@@ -1,12 +1,12 @@
 import { ChevronDown, ChevronRight, Loader2 } from "lucide-react";
 import { useState } from "react";
-import { Button } from "../button";
+import { Button } from "../../button";
 import {
   Collapsible,
   CollapsibleContent,
   CollapsibleTrigger,
-} from "../collapsible";
-import { EventData } from "./index";
+} from "../../collapsible";
+import { EventData } from "../index";
 
 export function ChatEvents({
   data,
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-image.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-image.tsx
similarity index 88%
rename from templates/types/streaming/nextjs/app/components/ui/chat/chat-image.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-image.tsx
index 056092135df69b3490348c4e79bf3b667a0f71fd..2de28c3d3378c9e18971e25557afc818731cc5b3 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-image.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-image.tsx
@@ -1,5 +1,5 @@
 import Image from "next/image";
-import { type ImageData } from "./index";
+import { type ImageData } from "../index";
 
 export function ChatImage({ data }: { data: ImageData }) {
   return (
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-sources.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-sources.tsx
similarity index 91%
rename from templates/types/streaming/nextjs/app/components/ui/chat/chat-sources.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-sources.tsx
index eb51b9aa80178ed80d427af3ce036195e11b227a..a43664364a17fbdb516844ac9550307edc0c197d 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-sources.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-sources.tsx
@@ -1,10 +1,14 @@
 import { Check, Copy } from "lucide-react";
 import { useMemo } from "react";
-import { Button } from "../button";
-import { HoverCard, HoverCardContent, HoverCardTrigger } from "../hover-card";
-import { SourceData } from "./index";
-import { useCopyToClipboard } from "./use-copy-to-clipboard";
-import PdfDialog from "./widgets/PdfDialog";
+import { Button } from "../../button";
+import {
+  HoverCard,
+  HoverCardContent,
+  HoverCardTrigger,
+} from "../../hover-card";
+import { useCopyToClipboard } from "../hooks/use-copy-to-clipboard";
+import { SourceData } from "../index";
+import PdfDialog from "../widgets/PdfDialog";
 
 const SCORE_THRESHOLD = 0.3;
 
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-tools.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-tools.tsx
similarity index 86%
rename from templates/types/streaming/nextjs/app/components/ui/chat/chat-tools.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-tools.tsx
index 268b4360d0c812a948581b489ee9f4f4267df642..202f98233f80d0200316456e0abade95e397c97b 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-tools.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-tools.tsx
@@ -1,5 +1,5 @@
-import { ToolData } from "./index";
-import { WeatherCard, WeatherData } from "./widgets/WeatherCard";
+import { ToolData } from "../index";
+import { WeatherCard, WeatherData } from "../widgets/WeatherCard";
 
 // TODO: If needed, add displaying more tool outputs here
 export default function ChatTools({ data }: { data: ToolData }) {
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/codeblock.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/codeblock.tsx
similarity index 97%
rename from templates/types/streaming/nextjs/app/components/ui/chat/codeblock.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/codeblock.tsx
index 014a0fc3afb58366508bf2ab5d4314b6bfc4abc7..e71a408cc8031385703af2a31fe2a706326dd9c1 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/codeblock.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/codeblock.tsx
@@ -5,8 +5,8 @@ import { FC, memo } from "react";
 import { Prism, SyntaxHighlighterProps } from "react-syntax-highlighter";
 import { coldarkDark } from "react-syntax-highlighter/dist/cjs/styles/prism";
 
-import { Button } from "../button";
-import { useCopyToClipboard } from "./use-copy-to-clipboard";
+import { Button } from "../../button";
+import { useCopyToClipboard } from "../hooks/use-copy-to-clipboard";
 
 // TODO: Remove this when @type/react-syntax-highlighter is updated
 const SyntaxHighlighter = Prism as unknown as FC<SyntaxHighlighterProps>;
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/csv-content.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/csv-content.tsx
similarity index 75%
rename from templates/types/streaming/nextjs/app/components/ui/chat/csv-content.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/csv-content.tsx
index 1a84d9786c5e9b96f78767b7d04f1490eee155d4..dae53cd7df7bade8b6707f8587c7700086a88e79 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/csv-content.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/csv-content.tsx
@@ -1,5 +1,5 @@
-import { CsvData } from ".";
-import UploadCsvPreview from "../upload-csv-preview";
+import UploadCsvPreview from "../../upload-csv-preview";
+import { CsvData } from "../index";
 
 export default function CsvContent({ data }: { data: CsvData }) {
   if (!data.csvFiles.length) return null;
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-message.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/index.tsx
similarity index 96%
rename from templates/types/streaming/nextjs/app/components/ui/chat/chat-message.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/index.tsx
index 7d346a7edef7db5aaa05f8b8d589518bafdb5d69..bff2d0db60236a22bf35370d463359f7111674df 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-message.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/index.tsx
@@ -2,13 +2,8 @@ import { Check, Copy } from "lucide-react";
 
 import { Message } from "ai";
 import { Fragment } from "react";
-import { Button } from "../button";
-import ChatAvatar from "./chat-avatar";
-import { ChatEvents } from "./chat-events";
-import { ChatImage } from "./chat-image";
-import { ChatSources } from "./chat-sources";
-import ChatTools from "./chat-tools";
-import CsvContent from "./csv-content";
+import { Button } from "../../button";
+import { useCopyToClipboard } from "../hooks/use-copy-to-clipboard";
 import {
   CsvData,
   EventData,
@@ -18,9 +13,14 @@ import {
   SourceData,
   ToolData,
   getAnnotationData,
-} from "./index";
+} from "../index";
+import ChatAvatar from "./chat-avatar";
+import { ChatEvents } from "./chat-events";
+import { ChatImage } from "./chat-image";
+import { ChatSources } from "./chat-sources";
+import ChatTools from "./chat-tools";
+import CsvContent from "./csv-content";
 import Markdown from "./markdown";
-import { useCopyToClipboard } from "./use-copy-to-clipboard";
 
 type ContentDisplayConfig = {
   order: number;
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/markdown.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/markdown.tsx
similarity index 100%
rename from templates/types/streaming/nextjs/app/components/ui/chat/markdown.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/markdown.tsx
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-messages.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-messages.tsx
index e2e81e2d9c7174ae16119b2dc3d7644596d04226..0fbdc30450125265557bc31d46fd9cdc04bdc70a 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-messages.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-messages.tsx
@@ -5,7 +5,7 @@ import { Button } from "../button";
 import ChatActions from "./chat-actions";
 import ChatMessage from "./chat-message";
 import { ChatHandler } from "./chat.interface";
-import { useClientConfig } from "./use-config";
+import { useClientConfig } from "./hooks/use-config";
 
 export default function ChatMessages(
   props: Pick<
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/use-config.ts b/templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-config.ts
similarity index 100%
rename from templates/types/streaming/nextjs/app/components/ui/chat/use-config.ts
rename to templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-config.ts
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/use-copy-to-clipboard.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-copy-to-clipboard.tsx
similarity index 100%
rename from templates/types/streaming/nextjs/app/components/ui/chat/use-copy-to-clipboard.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-copy-to-clipboard.tsx
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/use-csv.ts b/templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-csv.ts
similarity index 95%
rename from templates/types/streaming/nextjs/app/components/ui/chat/use-csv.ts
rename to templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-csv.ts
index afdbacaa3458405938924db8bc76d56670c7953d..56e1d0831acaeaddf70150d60410491e33cc0754 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/use-csv.ts
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-csv.ts
@@ -1,7 +1,7 @@
 "use client";
 
 import { useState } from "react";
-import { CsvFile } from ".";
+import { CsvFile } from "../chat";
 
 export function useCsv() {
   const [files, setFiles] = useState<CsvFile[]>([]);