diff --git a/lib/utils/url-utils.js b/lib/utils/url-utils.js
--- a/lib/utils/url-utils.js
+++ b/lib/utils/url-utils.js
@@ -8,6 +8,7 @@
   verify?: string,
   calendar?: boolean,
   chat?: boolean,
+  apps?: boolean,
   thread?: string,
   ...
 };
@@ -18,6 +19,7 @@
 const verifyRegex = new RegExp('(/|^)verify/([a-f0-9]+)(/|$)', 'i');
 const calendarRegex = new RegExp('(/|^)calendar(/|$)', 'i');
 const chatRegex = new RegExp('(/|^)chat(/|$)', 'i');
+const appsRegex = new RegExp('(/|^)apps(/|$)', 'i');
 
 function infoFromURL(url: string): URLInfo {
   const yearMatches = yearRegex.exec(url);
@@ -26,6 +28,7 @@
   const verifyMatches = verifyRegex.exec(url);
   const calendarTest = calendarRegex.test(url);
   const chatTest = chatRegex.test(url);
+  const appsTest = appsRegex.test(url);
   const returnObj = {};
   if (yearMatches) {
     returnObj.year = parseInt(yearMatches[2], 10);
@@ -47,6 +50,8 @@
     returnObj.calendar = true;
   } else if (chatTest) {
     returnObj.chat = true;
+  } else if (appsTest) {
+    returnObj.apps = true;
   }
   return returnObj;
 }
diff --git a/web/app.react.js b/web/app.react.js
--- a/web/app.react.js
+++ b/web/app.react.js
@@ -31,6 +31,7 @@
 import type { Dispatch } from 'lib/types/redux-types';
 import { registerConfig } from 'lib/utils/config';
 
+import AppsDirectory from './apps/apps-directory.react';
 import Calendar from './calendar/calendar.react';
 import Chat from './chat/chat.react';
 import InputStateContainer from './input/input-state-container.react';
@@ -149,6 +150,8 @@
       mainContent = <Calendar url={this.props.location.pathname} />;
     } else if (this.props.navInfo.tab === 'chat') {
       mainContent = <Chat />;
+    } else if (this.props.navInfo.tab === 'apps') {
+      mainContent = <AppsDirectory />;
     }
 
     return (
diff --git a/web/apps/apps-directory.react.js b/web/apps/apps-directory.react.js
new file mode 100644
--- /dev/null
+++ b/web/apps/apps-directory.react.js
@@ -0,0 +1,9 @@
+// @flow
+
+import * as React from 'react';
+
+function AppsDirectory(): React.Node {
+  return <div style={{ color: 'white' }}>Apps directory</div>;
+}
+
+export default AppsDirectory;
diff --git a/web/sidebar/app-switcher.react.js b/web/sidebar/app-switcher.react.js
--- a/web/sidebar/app-switcher.react.js
+++ b/web/sidebar/app-switcher.react.js
@@ -71,6 +71,19 @@
     ],
   );
 
+  const onClickApps = React.useCallback(
+    (event: SyntheticEvent<HTMLAnchorElement>) => {
+      event.preventDefault();
+      dispatch({
+        type: updateNavInfoActionType,
+        payload: {
+          tab: 'apps',
+        },
+      });
+    },
+    [dispatch],
+  );
+
   invariant(viewerID, 'should be set');
   let chatBadge = null;
   if (boundUnreadCount > 0) {
@@ -83,6 +96,9 @@
   const chatNavClasses = classNames({
     [css['current-tab']]: navInfo.tab === 'chat',
   });
+  const appsNavClasses = classNames({
+    [css['current-tab']]: navInfo.tab === 'apps',
+  });
 
   return (
     <div className={css.appSwitcherContainer}>
@@ -102,6 +118,12 @@
             <a onClick={onClickCalendar}>Calendar</a>
           </p>
         </li>
+        <li>
+          <p className={appsNavClasses}>
+            <SWMansionIcon icon="wrench" size={24} />
+            <a onClick={onClickApps}>Apps</a>
+          </p>
+        </li>
       </ul>
     </div>
   );
diff --git a/web/types/nav-types.js b/web/types/nav-types.js
--- a/web/types/nav-types.js
+++ b/web/types/nav-types.js
@@ -5,7 +5,7 @@
 
 export type NavInfo = {
   ...$Exact<BaseNavInfo>,
-  +tab: 'calendar' | 'chat',
+  +tab: 'calendar' | 'chat' | 'apps',
   +activeChatThreadID: ?string,
   +pendingThread?: ThreadInfo,
 };
diff --git a/web/url-utils.js b/web/url-utils.js
--- a/web/url-utils.js
+++ b/web/url-utils.js
@@ -97,8 +97,15 @@
     activeChatThreadID = navInfo.activeChatThreadID;
   }
 
+  let tab = 'chat';
+  if (urlInfo.calendar) {
+    tab = 'calendar';
+  } else if (urlInfo.apps) {
+    tab = 'apps';
+  }
+
   return {
-    tab: urlInfo.chat ? 'chat' : 'calendar',
+    tab,
     startDate: startDateForYearAndMonth(year, month),
     endDate: endDateForYearAndMonth(year, month),
     activeChatThreadID,