diff --git a/main.js b/main.js
index 42f233a90cdf22097b0c06032e2934dee4c617be..9d1f29c10c4728f9d7f49875260bf7a8d660a3a5 100644
--- a/main.js
+++ b/main.js
@@ -34,6 +34,7 @@ client.on('connect', () => {
 
 let doors = {
   'ucc-door': new DoorInfo(),
+  'unisfa-door': new DoorInfo(),
 };
 
 const update_door_state = (door, state) => {
@@ -96,19 +97,24 @@ client.on('message', (topic, message) => {
 const send_error = (res, code) => {
   res.writeHead(code);
   res.end();
-}
+};
+
+const send_redirect = (res, code, loc) => {
+  res.writeHead(code, {'Location': loc});
+  res.end();
+};
 
 const send_json = (res, code, data) => {
   res.writeHead(code, {'Content-Type': 'application/json'});
   res.end(JSON.stringify(data));
-}
+};
 
 const send_file = (res, code, fname, ctype) => {
   const data = fs.readFileSync(fname);
 
   res.writeHead(code, {'Content-Type': ctype});
   res.end(data);
-}
+};
 
 // Serve state on http
 const server = http.createServer((req, res) => {
@@ -119,6 +125,10 @@ const server = http.createServer((req, res) => {
   }
 
   if (req.url === '/') {
+    return send_redirect(res, 307, '/ucc');
+  }
+
+  if (req.url === '/ucc') {
     if (doors['ucc-door'].state === null) {
       return send_file(res, 500, './pages/ucc_door_unavail.html', 'text/html');
     }
@@ -127,7 +137,16 @@ const server = http.createServer((req, res) => {
     return send_file(res, 200, fname, 'text/html');
   }
 
-  if (req.url === '/state') {
+  if (req.url === '/unisfa') {
+    if (doors['unisfa-door'].state === null) {
+      return send_file(res, 500, './pages/unisfa_door_unavail.html', 'text/html');
+    }
+
+    const fname = doors['unisfa-door'].state ? './pages/unisfa_door_open.html' : './pages/unisfa_door_closed.html';
+    return send_file(res, 200, fname, 'text/html');
+  }
+
+  if (req.url === '/state/ucc') {
     if (doors['ucc-door'].state === null) {
       return send_json(res, 500, null);
     }
@@ -135,7 +154,15 @@ const server = http.createServer((req, res) => {
     return send_json(res, 200, doors['ucc-door'].state);
   }
 
-  if (req.url === '/opener') {
+  if (req.url === '/state/unisfa') {
+    if (doors['unisfa-door'].state === null) {
+      return send_json(res, 500, null);
+    }
+
+    return send_json(res, 200, doors['unisfa-door'].state);
+  }
+
+  if (req.url === '/opener/ucc') {
     if (doors['ucc-door'].opener === null) {
       return send_json(res, 500, null);
     }
@@ -151,6 +178,14 @@ const server = http.createServer((req, res) => {
     return send_file(res, 200, './static/door_ucc_closed.jpg', 'image/jpeg');
   }
 
+  if (req.url === '/static/door_unisfa_open.jpg') {
+    return send_file(res, 200, './static/door_unisfa_open.jpg', 'image/jpeg');
+  }
+
+  if (req.url === '/static/door_unisfa_closed.jpg') {
+    return send_file(res, 200, './static/door_unisfa_closed.jpg', 'image/jpeg');
+  }
+
   return send_error(res, 404);
 });
 
diff --git a/pages/ucc_door_open.html b/pages/ucc_door_open.html
index 33695ed914060b1591303e3b3405367860bff4b5..761b502dadcc127e8e1e736ebd154e2c39a39968 100644
--- a/pages/ucc_door_open.html
+++ b/pages/ucc_door_open.html
@@ -16,7 +16,7 @@
       title="A wild Gary lurking in the open doorway to the UCC clubroom."
       >
     <script>
-      fetch('/opener').then(response => {
+      fetch('/opener/ucc').then(response => {
         response.json().then(opener => {
           if (opener) {
             document.getElementById('opener').innerText = opener;
diff --git a/pages/unisfa_door_closed.html b/pages/unisfa_door_closed.html
new file mode 100644
index 0000000000000000000000000000000000000000..02c27a0f7532aee8b084a31a20a826c4b5a23775
--- /dev/null
+++ b/pages/unisfa_door_closed.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>Unisfa Door Status</title>
+  </head>
+  <body>
+    <h1>Unisfa Door Status</h1>
+    <p>The door is currently closed.</p>
+    <img
+      src="/static/door_unisfa_closed.jpg"
+      width="756"
+      height="1008"
+      alt="A plain image of the Unisfa door. There are some posters stuck upon it."
+      title="A plain image of the Unisfa door. There are some posters stuck upon it."
+      >
+  </body>
+</html>
+
+<!-- vim: set ts=2 sts=2 sw=2 et: -->
diff --git a/pages/unisfa_door_open.html b/pages/unisfa_door_open.html
new file mode 100644
index 0000000000000000000000000000000000000000..e4e4024d2f1b47bdebe6d0d575b589686e418a67
--- /dev/null
+++ b/pages/unisfa_door_open.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>Unisfa Door Status</title>
+  </head>
+  <body>
+    <h1>Unisfa Door Status</h1>
+    <p>The door is currently open!</p>
+    <img
+      src="/static/door_unisfa_open.jpg"
+      width="756"
+      height="1008"
+      alt="The door is open, however the Guardian of the Books blocks your path. Tread carefully..."
+      title="The door is open, however the Guardian of the Books blocks your path. Tread carefully..."
+      >
+  </body>
+</html>
+
+<!-- vim: set ts=2 sts=2 sw=2 et: -->
diff --git a/pages/unisfa_door_unavail.html b/pages/unisfa_door_unavail.html
new file mode 100644
index 0000000000000000000000000000000000000000..1b8293c1398b34c5047189bffdf563cff81af55c
--- /dev/null
+++ b/pages/unisfa_door_unavail.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>Unisfa Door Status</title>
+  </head>
+  <body>
+    <h1>Unisfa Door Status</h1>
+    <p>The door sensor is currently unavailable. Sorry :-(</p>
+  </body>
+</html>
+
+<!-- vim: set ts=2 sts=2 sw=2 et: -->
diff --git a/static/door_unisfa_closed.jpg b/static/door_unisfa_closed.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..ad965cfb7d1f4a58a8b331eaad45123d77594db5
Binary files /dev/null and b/static/door_unisfa_closed.jpg differ
diff --git a/static/door_unisfa_open.jpg b/static/door_unisfa_open.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..efce08c24982abfd97b50994e79bd1c86fa6c451
Binary files /dev/null and b/static/door_unisfa_open.jpg differ