diff --git a/src/Jackett/Content/custom.js b/src/Jackett/Content/custom.js
index 4832911ca780a0f46d85827a17f259956ddfc581..f0bb94de78f2ac2bc7db20b6ded37f8216e03dc5 100644
--- a/src/Jackett/Content/custom.js
+++ b/src/Jackett/Content/custom.js
@@ -1,15 +1,17 @@
-$(document).ready(function () {
+var basePath = "";
+
+$(document).ready(function () {
     $.ajaxSetup({ cache: false });
     window.jackettIsLocal = window.location.hostname === 'localhost' ||
                     window.location.hostname === '127.0.0.1';
 
     bindUIButtons();
-    reloadIndexers();
     loadJackettSettings();
+    reloadIndexers();
 });
 
 function getJackettConfig(callback) {
-    var jqxhr = $.get("/admin/get_jackett_config", function (data) {
+    var jqxhr = $.get("get_jackett_config", function (data) {
 
         callback(data);
     }).fail(function () {
@@ -22,6 +24,8 @@ function loadJackettSettings() {
         $("#api-key-input").val(data.config.api_key);
         $("#app-version").html(data.app_version);
         $("#jackett-port").val(data.config.port);
+        $("#jackett-basepathoverride").val(data.config.basepathoverride);
+        basePath = data.config.basepathoverride;
         $("#jackett-savedir").val(data.config.blackholedir);
         $("#jackett-allowext").attr('checked', data.config.external);
         $("#jackett-allowupdate").attr('checked', data.config.updatedisabled);
@@ -39,7 +43,7 @@ function reloadIndexers() {
     $('#indexers').hide();
     $('#indexers > .indexer').remove();
     $('#unconfigured-indexers').empty();
-    var jqxhr = $.get("/admin/get_indexers", function (data) {
+    var jqxhr = $.get("get_indexers", function (data) {
         displayIndexers(data.items);
     }).fail(function () {
         doNotify("Error loading indexers, request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
@@ -52,8 +56,8 @@ function displayIndexers(items) {
     $('#unconfigured-indexers-template').empty();
     for (var i = 0; i < items.length; i++) {
         var item = items[i];
-        item.torznab_host = resolveUrl("/torznab/" + item.id);
-        item.potato_host = resolveUrl("/potato/" + item.id);
+        item.torznab_host = resolveUrl("/" + basePath + "/torznab/" + item.id);
+        item.potato_host = resolveUrl("/" + basePath + "/potato/" + item.id);
         if (item.configured)
             $('#indexers').append(indexerTemplate(item));
         else
@@ -92,7 +96,7 @@ function prepareDeleteButtons() {
         var $btn = $(btn);
         var id = $btn.data("id");
         $btn.click(function () {
-            var jqxhr = $.post("/admin/delete_indexer", JSON.stringify({ indexer: id }), function (data) {
+            var jqxhr = $.post("delete_indexer", JSON.stringify({ indexer: id }), function (data) {
                 if (data.result == "error") {
                     doNotify("Delete error for " + id + "\n" + data.error, "danger", "glyphicon glyphicon-alert");
                 }
@@ -125,7 +129,7 @@ function prepareTestButtons() {
         var id = $btn.data("id");
         $btn.click(function () {
             doNotify("Test started for " + id, "info", "glyphicon glyphicon-transfer");
-            var jqxhr = $.post("/admin/test_indexer", JSON.stringify({ indexer: id }), function (data) {
+            var jqxhr = $.post("test_indexer", JSON.stringify({ indexer: id }), function (data) {
                 if (data.result == "error") {
                     doNotify("Test failed for " + id + ": \n" + data.error, "danger", "glyphicon glyphicon-alert");
                 }
@@ -141,7 +145,7 @@ function prepareTestButtons() {
 
 function displayIndexerSetup(id, link) {
 
-    var jqxhr = $.post("/admin/get_config_form", JSON.stringify({ indexer: id }), function (data) {
+    var jqxhr = $.post("get_config_form", JSON.stringify({ indexer: id }), function (data) {
         if (data.result == "error") {
             doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
             return;
@@ -247,7 +251,7 @@ function populateSetupForm(indexerId, name, config, caps, link) {
         $goButton.prop('disabled', true);
         $goButton.html($('#spinner').html());
 
-        var jqxhr = $.post("/admin/configure_indexer", JSON.stringify(data), function (data) {
+        var jqxhr = $.post("configure_indexer", JSON.stringify(data), function (data) {
             if (data.result == "error") {
                 if (data.config) {
                     populateConfigItems(configForm, data.config);
@@ -321,7 +325,7 @@ function bindUIButtons() {
     });
 
     $("#jackett-show-releases").click(function () {
-        var jqxhr = $.get("/admin/GetCache", function (data) {
+        var jqxhr = $.get("GetCache", function (data) {
             var releaseTemplate = Handlebars.compile($("#jackett-releases").html());
             var item = { releases: data, Title: 'Releases' };
             var releaseDialog = $(releaseTemplate(item));
@@ -403,7 +407,7 @@ function bindUIButtons() {
 
     $("#jackett-show-search").click(function () {
         $('#select-indexer-modal').remove();
-        var jqxhr = $.get("/admin/get_indexers", function (data) {
+        var jqxhr = $.get("get_indexers", function (data) {
             var scope = {
                 items: data.items
             };
@@ -459,7 +463,7 @@ function bindUIButtons() {
                 $('#searchResults').empty();
 
                 $('#jackett-search-perform').html($('#spinner').html());
-                var jqxhr = $.post("/admin/search", queryObj, function (data) {
+                var jqxhr = $.post("search", queryObj, function (data) {
                     $('#jackett-search-perform').html('Search trackers');
                     var resultsTemplate = Handlebars.compile($("#jackett-search-results").html());
                     var results = $('#searchResults');
@@ -534,7 +538,7 @@ function bindUIButtons() {
     });
 
     $("#view-jackett-logs").click(function () {
-        var jqxhr = $.get("/admin/GetLogs", function (data) {
+        var jqxhr = $.get("GetLogs", function (data) {
             var releaseTemplate = Handlebars.compile($("#jackett-logs").html());
             var item = { logs: data };
             var releaseDialog = $(releaseTemplate(item));
@@ -548,6 +552,7 @@ function bindUIButtons() {
 
     $("#change-jackett-port").click(function () {
         var jackett_port = $("#jackett-port").val();
+        var jackett_basepathoverride = $("#jackett-basepathoverride").val();
         var jackett_external = $("#jackett-allowext").is(':checked');
         var jackett_update = $("#jackett-allowupdate").is(':checked'); 
         var jackett_prerelease = $("#jackett-prerelease").is(':checked'); 
@@ -558,21 +563,17 @@ function bindUIButtons() {
             updatedisabled: jackett_update,
             prerelease: jackett_prerelease,
             blackholedir: $("#jackett-savedir").val(),
-            logging: jackett_logging
+            logging: jackett_logging,
+            basepathoverride: jackett_basepathoverride
         };
-        var jqxhr = $.post("/admin/set_config", JSON.stringify(jsonObject), function (data) {
+        var jqxhr = $.post("set_config", JSON.stringify(jsonObject), function (data) {
             if (data.result == "error") {
                 doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
                 return;
             } else {
                 doNotify("Redirecting you to complete configuration update..", "success", "glyphicon glyphicon-ok");
                 window.setTimeout(function () {
-                    url = window.location.href;
-                    if (data.external) {
-                        window.location.href = url.substr(0, url.lastIndexOf(":") + 1) + data.port;
-                    } else {
-                        window.location.href = 'http://127.0.0.1:' + data.port;
-                    }
+                    window.location.reload(true);
                 }, 3000);
 
             }
@@ -582,7 +583,7 @@ function bindUIButtons() {
     });
 
     $("#trigger-updater").click(function () {
-        var jqxhr = $.get("/admin/trigger_update", function (data) {
+        var jqxhr = $.get("trigger_update", function (data) {
             if (data.result == "error") {
                 doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
                 return;
@@ -598,7 +599,7 @@ function bindUIButtons() {
         var password = $("#jackett-adminpwd").val();
         var jsonObject = { password: password };
 
-        var jqxhr = $.post("/admin/set_admin_password", JSON.stringify(jsonObject), function (data) {
+        var jqxhr = $.post("set_admin_password", JSON.stringify(jsonObject), function (data) {
 
             if (data.result == "error") {
                 doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
diff --git a/src/Jackett/Content/index.html b/src/Jackett/Content/index.html
index 51591b9c082a318ff4b86eae4fbdfa8a7ec8ae52..94fea8d8febf00b6c04aaf122c16cfb7fe8de0fa 100644
--- a/src/Jackett/Content/index.html
+++ b/src/Jackett/Content/index.html
@@ -4,27 +4,27 @@
 <head>
     <meta charset="utf-8" />
     <link rel='shortcut icon' type='image/x-icon' href='/favicon.ico' />
-    <script src="../../libs/filesize.min.js"></script>
-    <script src="../../libs/jquery.min.js"></script>
-    <script src="../../libs/jquery.dataTables.min.js"></script>
-    <script src="../../libs/handlebars.min.js"></script>
-    <script src="../../libs/moment.min.js"></script>
-    <script src="../../libs/handlebarsmoment.js"></script>
-    <script src="../../bootstrap/bootstrap.min.js"></script>
-    <script src="../../libs/bootstrap-notify.js"></script>
+    <script src="../libs/filesize.min.js"></script>
+    <script src="../libs/jquery.min.js"></script>
+    <script src="../libs/jquery.dataTables.min.js"></script>
+    <script src="../libs/handlebars.min.js"></script>
+    <script src="../libs/moment.min.js"></script>
+    <script src="../libs/handlebarsmoment.js"></script>
+    <script src="../bootstrap/bootstrap.min.js"></script>
+    <script src="../libs/bootstrap-notify.js"></script>
     <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
 
-    <link href="../../bootstrap/bootstrap.min.css" rel="stylesheet">
-    <link href="../../animate.css" rel="stylesheet">
-    <link href="../../custom.css" rel="stylesheet">
-    <link href="../../css/jquery.dataTables.css" rel="stylesheet">
-    <link rel="stylesheet" href="../../css/font-awesome.min.css">
+    <link href="../bootstrap/bootstrap.min.css" rel="stylesheet">
+    <link href="../animate.css" rel="stylesheet">
+    <link href="../custom.css" rel="stylesheet">
+    <link href="../css/jquery.dataTables.css" rel="stylesheet">
+    <link rel="stylesheet" href="../css/font-awesome.min.css">
     <title>Jackett</title>
 </head>
 <body>
     <div id="page">
 
-        <img id="logo" src="../../jacket_medium.png" alt="Logo" /><span id="header-title">Jackett</span>
+        <img id="logo" src="../jacket_medium.png" alt="Logo" /><span id="header-title">Jackett</span>
 
         <div class="pull-right jackett-apikey">
             <span class="input-header">API Key: </span>
@@ -84,10 +84,13 @@
                 Logout
             </a>
         </div>
+        <div class="input-area">
+            <span class="input-header">Base Path Override: </span>
+            <input id="jackett-basepathoverride" class="form-control input-right" type="text" value="" placeholder="jackett/">
+        </div>
         <div class="input-area">
             <span class="input-header">Server port: </span>
             <input id="jackett-port" class="form-control input-right" type="text" value="" placeholder="9117">
-
         </div>
         <div class="input-area">
             <span class="input-header">Manual download blackhole directory: </span>
@@ -172,7 +175,7 @@
             <div class="indexer-logo">
                 <!-- Make section browser searchable -->
                 <span class="hidden-name">{{name}}</span>
-                <img alt="{{name}}" title="{{name}}" src="../../logos/{{id}}.png" />
+                <img alt="{{name}}" title="{{name}}" src="../logos/{{id}}.png" />
             </div>
             <div class="indexer-buttons">
                 <button class="btn btn-primary btn-sm indexer-setup" data-id="{{id}}" data-link="{{site_link}}">
@@ -206,7 +209,7 @@
             <div class="indexer-logo indexer-setup" data-id="{{id}}" data-link="{{site_link}}">
                 <!-- Make section browser searchable -->
                 <span class="hidden-name">{{name}}</span>
-                <img alt="{{name}}" title="{{name}}" src="../../logos/{{id}}.png" />
+                <img alt="{{name}}" title="{{name}}" src="../logos/{{id}}.png" />
               
             </div>
         </div>
@@ -478,6 +481,6 @@
         <span class="spinner glyphicon glyphicon-refresh"></span>
     </script>
 
-    <script src="../../custom.js"></script>
+    <script src="../custom.js"></script>
 </body>
 </html>
diff --git a/src/Jackett/Content/login.html b/src/Jackett/Content/login.html
index 194ad4bcdb694114f7e34b6cb3a33fe76b35a596..9f847549424e8e1602dd8723edf3d1a7d11d2705 100644
--- a/src/Jackett/Content/login.html
+++ b/src/Jackett/Content/login.html
@@ -6,28 +6,28 @@
 
     <link rel='shortcut icon' type='image/x-icon' href='/favicon.ico' />
 
-    <script src="../../libs/jquery.min.js"></script>
-    <script src="../../libs/jquery.dataTables.min.js"></script>
-    <script src="../../libs/handlebars.min.js"></script>
-    <script src="../../libs/moment.min.js"></script>
-    <script src="../../libs/handlebarsmoment.js"></script>
-    <script src="../../bootstrap/bootstrap.min.js"></script>
-    <script src="../../libs/bootstrap-notify.js"></script>
+    <script src="../libs/jquery.min.js"></script>
+    <script src="../libs/jquery.dataTables.min.js"></script>
+    <script src="../libs/handlebars.min.js"></script>
+    <script src="../libs/moment.min.js"></script>
+    <script src="../libs/handlebarsmoment.js"></script>
+    <script src="../bootstrap/bootstrap.min.js"></script>
+    <script src="../libs/bootstrap-notify.js"></script>
 
-    <link href="../../bootstrap/bootstrap.min.css" rel="stylesheet">
-    <link href="../../animate.css" rel="stylesheet">
-    <link href="../../custom.css" rel="stylesheet">
+    <link href="../bootstrap/bootstrap.min.css" rel="stylesheet">
+    <link href="../animate.css" rel="stylesheet">
+    <link href="../custom.css" rel="stylesheet">
 
     <title>Jackett</title>
 </head>
 <body>
     <div id="page">
 
-        <img id="logo" src="../../jacket_medium.png" /><span id="header-title">Jackett</span>
+        <img id="logo" src="../jacket_medium.png" /><span id="header-title">Jackett</span>
 
         <hr />
         <h1>Login</h1>
-        <form action="../Admin/Dashboard" method="post">
+        <form action="Dashboard" method="post">
             <div class="input-area">
                 <span class="input-header">Admin password</span>
                 <input id="password" name="password" class="form-control input-right" type="password">
diff --git a/src/Jackett/Controllers/AdminController.cs b/src/Jackett/Controllers/AdminController.cs
index 6750267dd6fafea65c9843bf394f685efe4d4ab7..5682938ca4fb54ba1810f48bc3b3636e029369dc 100644
--- a/src/Jackett/Controllers/AdminController.cs
+++ b/src/Jackett/Controllers/AdminController.cs
@@ -80,7 +80,7 @@ namespace Jackett.Controllers
             var ctx = Request.GetOwinContext();
             var authManager = ctx.Authentication;
             authManager.SignOut("ApplicationCookie");
-            return Redirect("/Admin/Dashboard");
+            return Redirect("Admin/Dashboard");
         }
 
         [HttpGet]
@@ -318,6 +318,7 @@ namespace Jackett.Controllers
                 cfg["prerelease"] = serverService.Config.UpdatePrerelease;
                 cfg["password"] = string.IsNullOrEmpty(serverService.Config.AdminPassword) ? string.Empty : serverService.Config.AdminPassword.Substring(0, 10);
                 cfg["logging"] = Startup.TracingEnabled;
+                cfg["basepathoverride"] = serverService.Config.BasePathOverride;
                
 
                 jsonReply["config"] = cfg;
@@ -349,9 +350,12 @@ namespace Jackett.Controllers
                 bool updateDisabled = (bool)postData["updatedisabled"];
                 bool preRelease = (bool)postData["prerelease"];
                 bool logging = (bool)postData["logging"];
+                string basePathOverride = (string)postData["basepathoverride"];
 
                 Engine.Server.Config.UpdateDisabled = updateDisabled;
                 Engine.Server.Config.UpdatePrerelease = preRelease;
+                Engine.Server.Config.BasePathOverride = basePathOverride;
+                Startup.BasePath = Engine.Server.BasePath();
                 Engine.Server.SaveConfig();
 
                 Engine.SetLogLevel(logging ? LogLevel.Debug : LogLevel.Info);
@@ -446,7 +450,7 @@ namespace Jackett.Controllers
 
         private void ConfigureCacheResults(List<TrackerCacheResult> results)
         {
-            var serverUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port);
+            var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
             foreach (var result in results)
             {
                 var link = result.Link;
diff --git a/src/Jackett/Controllers/PotatoController.cs b/src/Jackett/Controllers/PotatoController.cs
index 86992829c7de2b29feedb66d10a790e29165f337..dff0f7021b34d448f0fccd8ea3be1d7273e8242f 100644
--- a/src/Jackett/Controllers/PotatoController.cs
+++ b/src/Jackett/Controllers/PotatoController.cs
@@ -117,7 +117,7 @@ namespace Jackett.Controllers
             }
 
             releases = indexer.FilterResults(torznabQuery, releases);
-            var serverUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port);
+            var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
             var potatoResponse = new TorrentPotatoResponse();
 
             releases = TorznabUtil.FilterResultsToTitle(releases, torznabQuery.SanitizedSearchTerm, year);
diff --git a/src/Jackett/Controllers/TorznabController.cs b/src/Jackett/Controllers/TorznabController.cs
index 225066d1630e1ebb9dd5a2de1b9cc9bb19fa1d77..224f006687f3e4b6b2ad533dca6d7864651e8e80 100644
--- a/src/Jackett/Controllers/TorznabController.cs
+++ b/src/Jackett/Controllers/TorznabController.cs
@@ -100,7 +100,7 @@ namespace Jackett.Controllers
 
             logger.Info(logBuilder.ToString());
 
-            var serverUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port);
+            var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
             var resultPage = new ResultPage(new ChannelInfo
             {
                 Title = indexer.DisplayName,
diff --git a/src/Jackett/Models/Config/ServerConfig.cs b/src/Jackett/Models/Config/ServerConfig.cs
index eda58eab76323370da0f24f2e783d7cd8d4e9572..5b18ee2cd29d8bb8b3eb976e10a53134360ebd26 100644
--- a/src/Jackett/Models/Config/ServerConfig.cs
+++ b/src/Jackett/Models/Config/ServerConfig.cs
@@ -23,6 +23,7 @@ namespace Jackett.Models.Config
         public string BlackholeDir { get; set; }
         public bool UpdateDisabled { get; set; }
         public bool UpdatePrerelease { get; set; }
+        public string BasePathOverride { get; set; }
 
         public string[] GetListenAddresses(bool? external = null)
         {
diff --git a/src/Jackett/Services/ServerService.cs b/src/Jackett/Services/ServerService.cs
index bcfda2a704eea1c4135faf889e8e82dcad8758d7..e7fcba27b073aa382f2ed8ee834af10e7db11c5e 100644
--- a/src/Jackett/Services/ServerService.cs
+++ b/src/Jackett/Services/ServerService.cs
@@ -19,6 +19,7 @@ using System.Net;
 using System.Net.NetworkInformation;
 using System.Security.Cryptography;
 using System.Text;
+using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using System.Web;
 
@@ -32,7 +33,8 @@ namespace Jackett.Services
         void ReserveUrls(bool doInstall = true);
         ServerConfig Config { get; }
         void SaveConfig();
-        Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "t.torrent");
+        Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "t.torrent");
+        string BasePath();
     }
 
     public class ServerService : IServerService
@@ -77,6 +79,23 @@ namespace Jackett.Services
             return new Uri(proxyLink);
         }
 
+        public string BasePath()
+        {
+            if (config.BasePathOverride == null || config.BasePathOverride == "") {
+                return "/";
+            }
+            var path = config.BasePathOverride;
+            if (!path.EndsWith("/"))
+            {
+                path = path + "/";
+            }
+            if (!path.StartsWith("/"))
+            {
+                path = "/" + path;
+            }
+            return path;
+        }
+
         private void LoadConfig()
         {
             // Load config
@@ -139,6 +158,7 @@ namespace Jackett.Services
             logger.Info("Starting web server at " + config.GetListenAddresses()[0]);
             var startOptions = new StartOptions();
             config.GetListenAddresses().ToList().ForEach(u => startOptions.Urls.Add(u));
+            Startup.BasePath = BasePath();
             _server = WebApp.Start<Startup>(startOptions);
             logger.Debug("Web server started");
             updater.StartUpdateChecker();
diff --git a/src/Jackett/Startup.cs b/src/Jackett/Startup.cs
index 5aa8df8edba5b8e35a9443977fddc1f048e29784..3fb1814ba11845b1384496e1f75366bd3da60d48 100644
--- a/src/Jackett/Startup.cs
+++ b/src/Jackett/Startup.cs
@@ -58,6 +58,12 @@ namespace Jackett
             set;
         }
 
+        public static string BasePath
+        {
+            get;
+            set;
+        }
+
         public void Configuration(IAppBuilder appBuilder)
         {
             // Configure Web API for self-host. 
diff --git a/src/Jackett/Utils/WebApiRootRedirectMiddleware.cs b/src/Jackett/Utils/WebApiRootRedirectMiddleware.cs
index 68959f76d24e879b8f07401ed24858ad890e077d..fe4f7ac567c745f62817fb463678993d64516d99 100644
--- a/src/Jackett/Utils/WebApiRootRedirectMiddleware.cs
+++ b/src/Jackett/Utils/WebApiRootRedirectMiddleware.cs
@@ -1,4 +1,5 @@
-using Microsoft.Owin;
+using Jackett.Services;
+using Microsoft.Owin;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -11,7 +12,7 @@ namespace Jackett.Utils
     {
         public WebApiRootRedirectMiddleware(OwinMiddleware next)
             : base(next)
-        { 
+        {
         }
 
         public async override Task Invoke(IOwinContext context)
@@ -21,7 +22,9 @@ namespace Jackett.Utils
             {
                 // 301 is the status code of permanent redirect
                 context.Response.StatusCode = 301;
-                context.Response.Headers.Set("Location", "/Admin/Dashboard");
+                var redir = Startup.BasePath + "Admin/Dashboard";
+                Engine.Logger.Info("redirecting to " + redir);
+                context.Response.Headers.Set("Location", redir);
             }
             else
             {