diff --git a/apps/server/src/projectFaviconRoute.test.ts b/apps/server/src/projectFaviconRoute.test.ts
index a346e513eb..03d9893fff 100644
--- a/apps/server/src/projectFaviconRoute.test.ts
+++ b/apps/server/src/projectFaviconRoute.test.ts
@@ -117,6 +117,25 @@ describe("tryHandleProjectFaviconRequest", () => {
});
});
+ it("serves jpeg icons discovered from source metadata with the correct content type", async () => {
+ const projectDir = makeTempDir("t3code-favicon-route-jpeg-");
+ const iconPath = path.join(projectDir, "public", "brand", "logo.jpeg");
+ fs.mkdirSync(path.dirname(iconPath), { recursive: true });
+ fs.writeFileSync(
+ path.join(projectDir, "index.html"),
+ '',
+ );
+ fs.writeFileSync(iconPath, "jpeg-favicon", "utf8");
+
+ await withRouteServer(async (baseUrl) => {
+ const pathname = `/api/project-favicon?cwd=${encodeURIComponent(projectDir)}`;
+ const response = await request(baseUrl, pathname);
+ expect(response.statusCode).toBe(200);
+ expect(response.contentType).toContain("image/jpeg");
+ expect(response.body).toBe("jpeg-favicon");
+ });
+ });
+
it("resolves icon link when href appears before rel in HTML", async () => {
const projectDir = makeTempDir("t3code-favicon-route-html-order-");
const iconPath = path.join(projectDir, "public", "brand", "logo.svg");
diff --git a/apps/server/src/projectFaviconRoute.ts b/apps/server/src/projectFaviconRoute.ts
index cf234ad894..6fd1b3b2e7 100644
--- a/apps/server/src/projectFaviconRoute.ts
+++ b/apps/server/src/projectFaviconRoute.ts
@@ -1,13 +1,7 @@
import fs from "node:fs";
import http from "node:http";
import path from "node:path";
-
-const FAVICON_MIME_TYPES: Record = {
- ".png": "image/png",
- ".jpg": "image/jpeg",
- ".svg": "image/svg+xml",
- ".ico": "image/x-icon",
-};
+import Mime from "@effect/platform-node/Mime";
const FALLBACK_FAVICON_SVG = ``;
@@ -71,8 +65,7 @@ function isPathWithinProject(projectCwd: string, candidatePath: string): boolean
}
function serveFaviconFile(filePath: string, res: http.ServerResponse): void {
- const ext = path.extname(filePath).toLowerCase();
- const contentType = FAVICON_MIME_TYPES[ext] ?? "application/octet-stream";
+ const contentType = Mime.getType(filePath) ?? "application/octet-stream";
fs.readFile(filePath, (readErr, data) => {
if (readErr) {
res.writeHead(500, { "Content-Type": "text/plain" });