diff --git a/.gitignore b/.gitignore
index 5c81a37..47e7390 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ build/
dist/
artifacts/
*.tsbuildinfo
+bun.lockb
diff --git a/bun.lockb b/bun.lockb
deleted file mode 100644
index 332c38f..0000000
Binary files a/bun.lockb and /dev/null differ
diff --git a/electrobun.config.ts b/electrobun.config.ts
index 47e99c4..af24b00 100644
--- a/electrobun.config.ts
+++ b/electrobun.config.ts
@@ -4,7 +4,7 @@ export default {
app: {
name: "yafw",
identifier: "yafw.electrobun.dev",
- version: "0.7.3",
+ version: "0.7.4",
},
build: {
// Vite builds to dist/, Electrobun copies from there into the bundle
diff --git a/package.json b/package.json
index ed19f08..f5d25f4 100644
--- a/package.json
+++ b/package.json
@@ -8,14 +8,16 @@
"dev:hmr": "concurrently \"bun run hmr\" \"bun run start\"",
"hmr": "vite --port 5173",
"build:canary": "bun run scripts/patch-win-icons.js && vite build && electrobun build --env=canary",
- "build:stable": "bun run scripts/patch-win-icons.js && vite build && electrobun build --env=stable"
+ "build:stable": "bun run scripts/patch-win-icons.js && vite build && electrobun build --env=stable",
+ "build:web": "vite-react-ssg build"
},
"dependencies": {
"@ffmpeg/ffmpeg": "^0.12.15",
"@ffmpeg/util": "^0.12.2",
"electrobun": "^1.18.4-beta.3",
"react": "^18.3.1",
- "react-dom": "^18.3.1"
+ "react-dom": "^18.3.1",
+ "react-router-dom": "^6.28.0"
},
"devDependencies": {
"@types/bun": "latest",
@@ -27,6 +29,7 @@
"postcss": "^8.4.49",
"tailwindcss": "^3.4.16",
"typescript": "^5.7.2",
- "vite": "^6.0.3"
+ "vite": "^6.0.3",
+ "vite-react-ssg": "^0.9.1-beta.1"
}
}
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..956d4e1
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,4 @@
+User-agent: *
+Allow: /
+
+Sitemap: https://yafw.valentinrapp.fr/sitemap.xml
diff --git a/public/sitemap.xml b/public/sitemap.xml
new file mode 100644
index 0000000..fd98655
--- /dev/null
+++ b/public/sitemap.xml
@@ -0,0 +1,9 @@
+
+
+
+ https://yafw.valentinrapp.fr/
+ 2026-06-23
+ monthly
+ 1.0
+
+
diff --git a/src/mainview/App.tsx b/src/mainview/App.tsx
index 73620ba..131a247 100644
--- a/src/mainview/App.tsx
+++ b/src/mainview/App.tsx
@@ -9,7 +9,7 @@ import { useElectrobun } from "./hooks/useElectrobun";
import { Updating } from "./components/Updating";
import { isMac } from "./env";
-const App = () => {
+const ClientApp = () => {
const editorState = useVideoEditor();
const {
videoSrc,
@@ -65,6 +65,7 @@ const App = () => {
setCurrentPage={setCurrentPage}
videoSrc={videoSrc}
onChangeVideo={handleChangeVideo}
+ isStandalone={isStandalone}
/>
{/* Main Content Area */}
@@ -90,6 +91,7 @@ const App = () => {
onFileSelect={handleFileSelect}
onNativeBrowse={handleNativeBrowse}
onNavigateDownload={() => setCurrentPage("download")}
+ isStandalone={isStandalone}
/>
)}
@@ -108,4 +110,39 @@ const App = () => {
);
};
+const ServerApp = () => {
+ return (
+
+ );
+};
+
+const App = () => {
+ if (import.meta.env.SSR) {
+ return ;
+ }
+ return ;
+};
+
export default App;
diff --git a/src/mainview/components/FileDropZone.tsx b/src/mainview/components/FileDropZone.tsx
index d225a5a..c66c789 100644
--- a/src/mainview/components/FileDropZone.tsx
+++ b/src/mainview/components/FileDropZone.tsx
@@ -1,12 +1,16 @@
import { useRef, useState } from "react";
-import { isStandalone } from "../env";
interface FileDropZoneProps {
onFileSelect: (file: File) => void;
onNativeBrowse?: () => void;
+ isStandalone: boolean;
}
-export const FileDropZone = ({ onFileSelect, onNativeBrowse }: FileDropZoneProps) => {
+export const FileDropZone = ({
+ onFileSelect,
+ onNativeBrowse,
+ isStandalone,
+}: FileDropZoneProps) => {
const [isDragging, setIsDragging] = useState(false);
const fileInputRef = useRef(null);
diff --git a/src/mainview/components/Header.tsx b/src/mainview/components/Header.tsx
index 9a7673c..2590cbf 100644
--- a/src/mainview/components/Header.tsx
+++ b/src/mainview/components/Header.tsx
@@ -1,4 +1,4 @@
-import { isStandalone, isMac } from "../env";
+import { isMac } from "../env";
import logoUrl from "../assets/logo.png";
interface HeaderProps {
@@ -6,6 +6,7 @@ interface HeaderProps {
setCurrentPage: (page: "editor" | "download") => void;
videoSrc: string | null;
onChangeVideo: () => void;
+ isStandalone: boolean;
}
export const Header = ({
@@ -13,6 +14,7 @@ export const Header = ({
setCurrentPage,
videoSrc,
onChangeVideo,
+ isStandalone,
}: HeaderProps) => (
diff --git a/src/mainview/components/LandingPage.tsx b/src/mainview/components/LandingPage.tsx
index 7b87de1..ffd2315 100644
--- a/src/mainview/components/LandingPage.tsx
+++ b/src/mainview/components/LandingPage.tsx
@@ -1,17 +1,18 @@
import { FileDropZone } from "./FileDropZone";
-import { isStandalone } from "../env";
import logoUrl from "../assets/logo.png";
interface LandingPageProps {
onFileSelect: (file: File) => void;
onNativeBrowse: () => void;
onNavigateDownload: () => void;
+ isStandalone: boolean;
}
export const LandingPage = ({
onFileSelect,
onNativeBrowse,
onNavigateDownload,
+ isStandalone,
}: LandingPageProps) => (
<>
@@ -48,6 +49,7 @@ export const LandingPage = ({
onNativeBrowse={
isStandalone ? onNativeBrowse : undefined
}
+ isStandalone={isStandalone}
/>
diff --git a/src/mainview/hooks/useElectrobun.ts b/src/mainview/hooks/useElectrobun.ts
index 08b676c..ed4f94a 100644
--- a/src/mainview/hooks/useElectrobun.ts
+++ b/src/mainview/hooks/useElectrobun.ts
@@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from "react";
-import { isStandalone } from "../env";
+import { isStandalone as rawIsStandalone } from "../env";
import { type AppRPCType } from "../../shared/types";
let sharedElectroview: any = null;
@@ -10,9 +10,14 @@ const listeners = new Set<(ev: any, encoders: string[]) => void>();
export const useElectrobun = () => {
const [supportedEncoders, setSupportedEncoders] = useState
(sharedSupportedEncoders);
const [electroview, setElectroview] = useState(sharedElectroview);
+ const [isStandalone, setIsStandalone] = useState(false);
useEffect(() => {
- if (!isStandalone) return;
+ if (rawIsStandalone) {
+ setIsStandalone(true);
+ }
+
+ if (!rawIsStandalone) return;
if (sharedElectroview) {
setElectroview(sharedElectroview);
diff --git a/src/mainview/index.html b/src/mainview/index.html
index 8da4ec3..9a1eba3 100644
--- a/src/mainview/index.html
+++ b/src/mainview/index.html
@@ -3,7 +3,44 @@
+
+
YAFW - Yet Another FFmpeg Wrapper
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/mainview/main.tsx b/src/mainview/main.tsx
index 0de8dcd..c35fac2 100644
--- a/src/mainview/main.tsx
+++ b/src/mainview/main.tsx
@@ -1,10 +1,5 @@
-import { StrictMode } from "react";
-import { createRoot } from "react-dom/client";
+import { ViteReactSSG } from "vite-react-ssg/single-page";
import "./index.css";
import App from "./App";
-createRoot(document.getElementById("root")!).render(
-
-
- ,
-);
+export const createRoot = ViteReactSSG();
\ No newline at end of file
diff --git a/vite.config.ts b/vite.config.ts
index 293f198..743de98 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -4,6 +4,7 @@ import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
root: "src/mainview",
+ publicDir: "../../public",
build: {
outDir: "../../dist",
emptyOutDir: true,