diff --git a/install/check_lacked_trans.py b/install/check_lacked_trans.py
index 010cdb7a..5ccce923 100755
--- a/install/check_lacked_trans.py
+++ b/install/check_lacked_trans.py
@@ -59,6 +59,7 @@ def main():
           files_in(dir, 'onionshare_gui/mode') + \
           files_in(dir, 'onionshare_gui/mode/share_mode') + \
           files_in(dir, 'onionshare_gui/mode/receive_mode') + \
+          files_in(dir, 'onionshare_gui/mode/website_mode') + \
           files_in(dir, 'install/scripts') + \
           files_in(dir, 'tests')
     pysrc = [p for p in src if p.endswith('.py')]
diff --git a/install/requirements.txt b/install/requirements.txt
index 0abd773f..fff0b009 100644
--- a/install/requirements.txt
+++ b/install/requirements.txt
@@ -3,6 +3,7 @@ certifi==2019.3.9
 chardet==3.0.4
 Click==7.0
 Flask==1.0.2
+Flask-HTTPAuth
 future==0.17.1
 idna==2.8
 itsdangerous==1.1.0
diff --git a/onionshare/__init__.py b/onionshare/__init__.py
index 620ada98..dad092ed 100644
--- a/onionshare/__init__.py
+++ b/onionshare/__init__.py
@@ -51,6 +51,7 @@ def main(cwd=None):
     parser.add_argument('--connect-timeout', metavar='<int>', dest='connect_timeout', default=120, help="Give up connecting to Tor after a given amount of seconds (default: 120)")
     parser.add_argument('--stealth', action='store_true', dest='stealth', help="Use client authorization (advanced)")
     parser.add_argument('--receive', action='store_true', dest='receive', help="Receive shares instead of sending them")
+    parser.add_argument('--website', action='store_true', dest='website', help=strings._("help_website"))
     parser.add_argument('--config', metavar='config', default=False, help="Custom JSON config file location (optional)")
     parser.add_argument('-v', '--verbose', action='store_true', dest='verbose', help="Log OnionShare errors to stdout, and web errors to disk")
     parser.add_argument('filename', metavar='filename', nargs='*', help="List of files or folders to share")
@@ -68,10 +69,13 @@ def main(cwd=None):
     connect_timeout = int(args.connect_timeout)
     stealth = bool(args.stealth)
     receive = bool(args.receive)
+    website = bool(args.website)
     config = args.config
 
     if receive:
         mode = 'receive'
+    elif website:
+        mode = 'website'
     else:
         mode = 'share'
 
@@ -168,6 +172,15 @@ def main(cwd=None):
         print(e.args[0])
         sys.exit()
 
+    if mode == 'website':
+        # Prepare files to share
+        print(strings._("preparing_website"))
+        try:
+            web.website_mode.set_file_info(filenames)
+        except OSError as e:
+            print(e.strerror)
+            sys.exit(1)
+
     if mode == 'share':
         # Prepare files to share
         print("Compressing files.")
@@ -206,6 +219,8 @@ def main(cwd=None):
         # Build the URL
         if common.settings.get('public_mode'):
             url = 'http://{0:s}'.format(app.onion_host)
+        elif mode == 'website':
+            url = 'http://onionshare:{0:s}@{1:s}'.format(web.slug, app.onion_host)
         else:
             url = 'http://{0:s}/{1:s}'.format(app.onion_host, web.slug)
 
diff --git a/onionshare/web/web.py b/onionshare/web/web.py
index edaf75f1..0ba8c6b3 100644
--- a/onionshare/web/web.py
+++ b/onionshare/web/web.py
@@ -15,7 +15,7 @@ from .. import strings
 
 from .share_mode import ShareModeWeb
 from .receive_mode import ReceiveModeWeb, ReceiveModeWSGIMiddleware, ReceiveModeRequest
-
+from .website_mode import WebsiteModeWeb
 
 # Stub out flask's show_server_banner function, to avoiding showing warnings that
 # are not applicable to OnionShare
@@ -111,13 +111,15 @@ class Web(object):
         self.receive_mode = None
         if self.mode == 'receive':
             self.receive_mode = ReceiveModeWeb(self.common, self)
+        elif self.mode == 'website':
+            self.website_mode = WebsiteModeWeb(self.common, self)
         elif self.mode == 'share':
             self.share_mode = ShareModeWeb(self.common, self)
 
 
     def define_common_routes(self):
         """
-        Common web app routes between sending and receiving
+        Common web app routes between sending, receiving and website modes.
         """
         @self.app.errorhandler(404)
         def page_not_found(e):
diff --git a/onionshare/web/website_mode.py b/onionshare/web/website_mode.py
new file mode 100644
index 00000000..7b8429ae
--- /dev/null
+++ b/onionshare/web/website_mode.py
@@ -0,0 +1,154 @@
+import os
+import sys
+import tempfile
+import mimetypes
+from flask import Response, request, render_template, make_response, send_from_directory
+from flask_httpauth import HTTPBasicAuth
+
+from .. import strings
+
+
+class WebsiteModeWeb(object):
+    """
+    All of the web logic for share mode
+    """
+    def __init__(self, common, web):
+        self.common = common
+        self.common.log('WebsiteModeWeb', '__init__')
+
+        self.web = web
+        self.auth = HTTPBasicAuth()
+
+        # Information about the file to be shared
+        self.file_info = []
+        self.website_folder = ''
+        self.download_filesize = 0
+        self.visit_count = 0
+
+        self.users = { }
+
+        self.define_routes()
+
+    def define_routes(self):
+        """
+        The web app routes for sharing a website
+        """
+
+        @self.auth.get_password
+        def get_pw(username):
+            self.users['onionshare'] = self.web.slug
+
+            if self.common.settings.get('public_mode'):
+                return True  # let the request through, no questions asked!
+            elif username in self.users:
+                return self.users.get(username)
+            else:
+                return None
+
+        @self.web.app.route('/download/<path:page_path>')
+        @self.auth.login_required
+        def path_download(page_path):
+            return path_download(page_path)
+
+        @self.web.app.route('/<path:page_path>')
+        @self.auth.login_required
+        def path_public(page_path):
+            return path_logic(page_path)
+
+        @self.web.app.route("/")
+        @self.auth.login_required
+        def index_public():
+            return path_logic('')
+
+        def path_download(file_path=''):
+            """
+            Render the download links.
+            """
+            self.web.add_request(self.web.REQUEST_LOAD, request.path)
+            if not os.path.isfile(os.path.join(self.website_folder, file_path)):
+                return self.web.error404()
+
+            return send_from_directory(self.website_folder, file_path)
+
+        def path_logic(page_path=''):
+            """
+            Render the onionshare website.
+            """
+
+            self.web.add_request(self.web.REQUEST_LOAD, request.path)
+
+            if self.file_info['files']:
+                self.website_folder = os.path.dirname(self.file_info['files'][0]['filename'])
+            elif self.file_info['dirs']:
+                self.website_folder = self.file_info['dirs'][0]['filename']
+            else:
+                return self.web.error404()
+
+            if any((fname == 'index.html') for fname in os.listdir(self.website_folder)):
+                self.web.app.static_url_path = self.website_folder
+                self.web.app.static_folder = self.website_folder
+                if not os.path.isfile(os.path.join(self.website_folder, page_path)):
+                    page_path = os.path.join(page_path, 'index.html')
+
+                return send_from_directory(self.website_folder, page_path)
+
+            elif any(os.path.isfile(os.path.join(self.website_folder, i)) for i in os.listdir(self.website_folder)):
+                filenames = []
+                for i in os.listdir(self.website_folder):
+                    filenames.append(os.path.join(self.website_folder, i))
+
+                self.set_file_info(filenames)
+
+                r = make_response(render_template(
+                    'listing.html',
+                    file_info=self.file_info,
+                    filesize=self.download_filesize,
+                    filesize_human=self.common.human_readable_filesize(self.download_filesize)))
+
+                return self.web.add_security_headers(r)
+
+            else:
+                return self.web.error404()
+
+
+    def set_file_info(self, filenames, processed_size_callback=None):
+        """
+        Using the list of filenames being shared, fill in details that the web
+        page will need to display. This includes zipping up the file in order to
+        get the zip file's name and size.
+        """
+        self.common.log("WebsiteModeWeb", "set_file_info")
+        self.web.cancel_compression = True
+
+        self.cleanup_filenames = []
+
+        # build file info list
+        self.file_info = {'files': [], 'dirs': []}
+        for filename in filenames:
+            info = {
+                'filename': filename,
+                'basename': os.path.basename(filename.rstrip('/'))
+            }
+            if os.path.isfile(filename):
+                info['size'] = os.path.getsize(filename)
+                info['size_human'] = self.common.human_readable_filesize(info['size'])
+                self.file_info['files'].append(info)
+            if os.path.isdir(filename):
+                info['size'] = self.common.dir_size(filename)
+                info['size_human'] = self.common.human_readable_filesize(info['size'])
+                self.file_info['dirs'].append(info)
+
+            self.download_filesize += info['size']
+
+        self.file_info['files'] = sorted(self.file_info['files'], key=lambda k: k['basename'])
+        self.file_info['dirs'] = sorted(self.file_info['dirs'], key=lambda k: k['basename'])
+
+        # Check if there's only 1 file and no folders
+        if len(self.file_info['files']) == 1 and len(self.file_info['dirs']) == 0:
+            self.download_filename = self.file_info['files'][0]['filename']
+            self.download_filesize = self.file_info['files'][0]['size']
+
+            self.download_filesize = os.path.getsize(self.download_filename)
+
+
+        return True
diff --git a/share/templates/listing.html b/share/templates/listing.html
new file mode 100644
index 00000000..a514e5d2
--- /dev/null
+++ b/share/templates/listing.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+ <head>
+    <title>OnionShare</title>
+    <link href="/static/img/favicon.ico" rel="icon" type="image/x-icon" />
+    <link href="/static/css/style.css" rel="stylesheet" type="text/css" />
+  </head>
+  <body>
+
+    <header class="clearfix">
+      <div class="right">
+        <ul>
+          <li>Total size: <strong>{{ filesize_human }}</strong></li>
+        </ul>
+      </div>
+      <img class="logo" src="/static/img/logo.png" title="OnionShare">
+      <h1>OnionShare</h1>
+    </header>
+
+    <table class="file-list" id="file-list">
+      <tr>
+        <th id="filename-header">Filename</th>
+        <th id="size-header">Size</th>
+        <th></th>
+      </tr>
+
+      {% for info in file_info.files %}
+      <tr>
+        <td>
+          <img width="30" height="30" title="" alt="" src="/static/img/web_file.png" />
+          {{ info.basename }}
+        </td>
+        <td>{{ info.size_human }}</td>
+        <td><a href="/download/{{ info.basename }}">download</td>
+      </tr>
+      {% endfor %}
+    </table>
+    <script src="/static/js/send.js"></script>
+  </body>
+</html>