diff --git a/server/src/main.rs b/server/src/main.rs
index a44ec82..b3d6d34 100644
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -11,6 +11,7 @@ use rocket::{tokio, State};
 use serde::{Deserialize, Serialize};
 use std::collections::HashMap;
 use std::sync::{Arc, LazyLock, Weak};
+use rocket::fs::FileServer;
 use tokio::select;
 use word_grid::api::{APIGame, ApiState, Update};
 use word_grid::dictionary::{Dictionary, DictionaryImpl};
@@ -492,5 +493,6 @@ async fn room(
 fn rocket() -> _ {
     rocket::build()
         .manage(Mutex::new(RoomMap::new()))
+        .mount("/", FileServer::from("../ui/dist"))
         .mount("/", routes![room])
 }
diff --git a/ui/src/Game.tsx b/ui/src/Game.tsx
index 11c1e34..85a777e 100644
--- a/ui/src/Game.tsx
+++ b/ui/src/Game.tsx
@@ -37,7 +37,7 @@ export function Game(props: {
     const historyProcessedNumber = useRef<number>(0);
 
     let isGameOver = false;
-    if (api_state !== undefined) {
+    if (api_state != null) {
         isGameOver = api_state.public_information.game_state.type === "Ended";
     }
 
@@ -59,7 +59,7 @@ export function Game(props: {
     const [boardLetters, setBoardLetters] = useState<HighlightableLetterData[]>(() => {
         const newLetterData = [] as HighlightableLetterData[];
         for (let i = 0; i < GRID_LENGTH * GRID_LENGTH; i++) {
-            newLetterData.push(undefined);
+            newLetterData.push(null);
         }
         return newLetterData;
 
@@ -456,14 +456,14 @@ export function Game(props: {
                     disabled={isGameOver || !isPlayersTurn}
                     onClick={async () => {
                         const playedTiles = playerLetters.map((i) => {
-                            if (i === undefined) {
+                            if (i == null) {
                                 return null;
                             }
 
                             if (i.location === LocationType.GRID) {
                                 let result: PlayedTile = {
                                     index: i.index,
-                                    character: undefined
+                                    character: null
                                 };
                                 if (i.is_blank) {
                                     result.character = i.text;
diff --git a/ui/src/UI.tsx b/ui/src/UI.tsx
index 74b699b..be74107 100644
--- a/ui/src/UI.tsx
+++ b/ui/src/UI.tsx
@@ -16,12 +16,12 @@ import {APIPlayer, CellType} from "./api";
 
 
 export function TileSlot(props: {
-        tile?: React.JSX.Element | undefined,
+        tile?: React.JSX.Element | null,
         location: CoordinateData,
         tileDispatch: TileDispatch,
         arrowDispatch?: GridArrowDispatch,
 }): React.JSX.Element {
-    let isDraggable = props.tile !== undefined;
+    let isDraggable = props.tile != null;
 
     function onDragStart(e: React.DragEvent<HTMLDivElement>) {
         e.dataTransfer.effectAllowed = "move";
@@ -48,7 +48,7 @@ export function TileSlot(props: {
     } else if(props.location.location == LocationType.TRAY && props.tile != null && props.tile.props.data.text != ' ' && props.tile.props.data.text != '') {
         onClick = () => {
             props.tileDispatch({
-                action: TileDispatchActionType.MOVE_TO_ARROW, end: undefined, start: props.location,
+                action: TileDispatchActionType.MOVE_TO_ARROW, end: null, start: props.location,
             });
         }
     }
diff --git a/ui/src/api.ts b/ui/src/api.ts
index a9071e5..4ac8eba 100644
--- a/ui/src/api.ts
+++ b/ui/src/api.ts
@@ -1,5 +1,5 @@
 export interface Tray {
-    letters: (Letter | undefined)[];
+    letters: (Letter | null)[];
 }
 
 export interface ScoreResult {
@@ -14,7 +14,7 @@ export interface WordResult {
 
 export interface PlayedTile {
     index: number;
-    character: string | undefined;
+    character?: string;
 }
 
 export interface Difficulty {
@@ -41,7 +41,7 @@ export enum CellType {
     Start = "Start",
 }
 
-export type GameState = { type: "InProgress" } | { type: "Ended"; finisher: string | undefined; remaining_tiles: {[id: string]: Letter[]} };
+export type GameState = { type: "InProgress" } | { type: "Ended"; finisher?: string; remaining_tiles: {[id: string]: Letter[]} };
 
 export interface APIPlayer {
     name: string;
diff --git a/ui/src/multiplayer.tsx b/ui/src/multiplayer.tsx
index 046e2b8..48935b1 100644
--- a/ui/src/multiplayer.tsx
+++ b/ui/src/multiplayer.tsx
@@ -118,8 +118,8 @@ export function Menu(): React.JSX.Element {
                 </label>
             </div>
 
-            <button onClick={(e) => {
-                let socket = new WebSocket(`ws://localhost:8000/room/${roomName}?player_name=${playerName}`)
+            <button onClick={() => {
+                let socket = new WebSocket(`/room/${roomName}?player_name=${playerName}`)
                 socket.addEventListener("message", (event) => {
                     const input: ServerToClientMessage = JSON.parse(event.data);
                     if(input.type == "RoomChange"){
diff --git a/ui/src/utils.ts b/ui/src/utils.ts
index 44949f3..97ba0f5 100644
--- a/ui/src/utils.ts
+++ b/ui/src/utils.ts
@@ -58,7 +58,7 @@ export function matchCoordinate(playerLetters: PlayableLetterData[], coords: Coo
     for (let i=0; i<playerLetters.length; i++){
         let letter = playerLetters[i];
 
-        if (letter !== undefined && letter.location === coords.location && letter.index === coords.index) {
+        if (letter != null && letter.location === coords.location && letter.index === coords.index) {
             return i;
         }
     }
@@ -108,7 +108,7 @@ export function addNTimes<T>(array: T[], toAdd: T, times: number) {
     }
 }
 
-export function mergeTrays(existing: PlayableLetterData[], newer: (LetterData | undefined)[]): PlayableLetterData[] {
+export function mergeTrays(existing: PlayableLetterData[], newer: (LetterData | null)[]): PlayableLetterData[] {
 
     let trayLength = Math.max(existing.length, newer.length);