diff --git a/beat/web/reports/static/reports/app/controllers/reportController.js b/beat/web/reports/static/reports/app/controllers/reportController.js
index 3b729a02c7969e808cab7f016df7e12fe180f6f8..bd6a268937dca172534f8827a572649cc877a0ec 100644
--- a/beat/web/reports/static/reports/app/controllers/reportController.js
+++ b/beat/web/reports/static/reports/app/controllers/reportController.js
@@ -101,7 +101,6 @@ angular.module('reportApp').controller('reportController',['$scope', 'reportFact
 
 		// save groups data to the model
 		GroupsService.loadGroups($scope.report.content.groups);
-		GroupsService.saveUrlBase(`/${$scope.user}/${$scope.report_id}`);
 		const isEditable = $scope.report.is_owner && $scope.report.status === 'editable';
 		GroupsService.setEditable(isEditable);
 	}
diff --git a/beat/web/reports/static/reports/app/directives/edit/textItem.js b/beat/web/reports/static/reports/app/directives/edit/textItem.js
index c5b0df8d3a5d39b5668dbc9ab119ad3651e3d0a0..57296418f73d7eb35cdbc50b2dcadb22b922472f 100644
--- a/beat/web/reports/static/reports/app/directives/edit/textItem.js
+++ b/beat/web/reports/static/reports/app/directives/edit/textItem.js
@@ -26,7 +26,7 @@
  * 	displays a text report item
  */
 angular.module('reportApp')
-.directive("groupTextItem", ['GroupsService', '$sce', function(GroupsService, $sce){
+.directive("groupTextItem", ['GroupsService', '$sce', 'UrlService', 'reportFactory', function(GroupsService, $sce, UrlService, reportFactory){
 	return {
 		scope: {
 			group: '=',
@@ -54,7 +54,11 @@ angular.module('reportApp')
 			// handle compiling content
 			scope.compiledContent = { val: '' };
 			scope.compileContent = () => {
-				GroupsService.compileRST(scope.item.content)
+				let url = UrlService.getCompileRstUrl();
+				let content = scope.item.content;
+				console.log(url);
+
+				return reportFactory.compileRST(url, content)
 				.then(data => {
 					scope.compiledContent.val = data.data.html_str;
 				});
diff --git a/beat/web/reports/static/reports/app/factories/reportFactory.js b/beat/web/reports/static/reports/app/factories/reportFactory.js
index 4e930ae3d2a0ee479b1d546bd6f78e1c82b77148..21c9a419aaa8272863d38bf1ec4317c26e32c8b4 100644
--- a/beat/web/reports/static/reports/app/factories/reportFactory.js
+++ b/beat/web/reports/static/reports/app/factories/reportFactory.js
@@ -94,13 +94,11 @@ angular.module('reportApp').factory('reportFactory', ['$http', 'experimentFactor
 		});
 	};
 
-	reportFactory.compileRST = (urlSubstr, raw) => {
+	reportFactory.compileRST = (url, raw) => {
 		let data = {
 			raw
 		};
 
-		let url = `${urlBase}${urlSubstr}`;
-
 		return $http({
 			headers: {'Content-Type': 'application/json'},
 			url,
diff --git a/beat/web/reports/static/reports/app/services/groupsService.js b/beat/web/reports/static/reports/app/services/groupsService.js
index 11d237ace173802453fd110a9b25bc8c3d73ab7d..5410187409e96477e053f105583180c63c9b5ade 100644
--- a/beat/web/reports/static/reports/app/services/groupsService.js
+++ b/beat/web/reports/static/reports/app/services/groupsService.js
@@ -314,16 +314,6 @@ angular.module('reportApp').factory('GroupsService', ['reportFactory', function(
 		return groupData.find(g => g.reportItems.find(i => i.id === id));
 	};
 
-	groupsServiceInstance.urlBase = '';
-	groupsServiceInstance.saveUrlBase = (url) => {
-		groupsServiceInstance.urlBase = url;
-	};
-
-	groupsServiceInstance.compileRST = (raw) => {
-		let url = `${groupsServiceInstance.urlBase}/rst/`;
-		return reportFactory.compileRST(url, raw);
-	};
-
 	// helper to assert that a group exists
 	function checkForGroup (groupName) {
 		if(!groupData.find(g => g.name === groupName)){
diff --git a/beat/web/reports/static/reports/app/services/urlService.js b/beat/web/reports/static/reports/app/services/urlService.js
new file mode 100644
index 0000000000000000000000000000000000000000..aaddd515274041c9a79286012560c316ea12def2
--- /dev/null
+++ b/beat/web/reports/static/reports/app/services/urlService.js
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/
+ * Contact: beat.support@idiap.ch
+ *
+ * This file is part of the beat.web module of the BEAT platform.
+ *
+ * Commercial License Usage
+ * Licensees holding valid commercial BEAT licenses may use this file in
+ * accordance with the terms contained in a written agreement between you
+ * and Idiap. For further information contact tto@idiap.ch
+ *
+ * Alternatively, this file may be used under the terms of the GNU Affero
+ * Public License version 3 as published by the Free Software and appearing
+ * in the file LICENSE.AGPL included in the packaging of this file.
+ * The BEAT platform is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero Public License along
+ * with the BEAT platform. If not, see http://www.gnu.org/licenses/.
+ */
+
+/*
+ * UrlService
+ * Desc:
+ * 	Helper functionality to generate URLs for the reports app
+ */
+angular.module('reportApp').factory('UrlService', [function(){
+	// const path segments
+	const experimentSegment = 'experiments/';
+	const blockSegment = 'algorithms/';
+	const databaseSegment = 'databases/';
+	const apiSegment = 'api/v1/';
+
+	// the protocol, address, and port number
+	let prefix = '';
+	// the path to the current report, by username & report name
+	let reportByName;
+	// the path to the current report, by report number
+	let reportByNumber;
+
+	// extracts info from jQuery's ajaxSettings current URL
+	const extractUsingCurrentUrl = () => {
+		console.log($.ajaxSettings);
+		const url = $.ajaxSettings.url;
+		const idxSplit = url.indexOf('reports');
+		const path = url.slice(idxSplit);
+
+		prefix = url.slice(0, idxSplit);
+		// find how many '/' are in path via splitting str on '/'
+		if(path.split('/').length === 2){
+			// report number
+			reportByNumber = path;
+		} else {
+			// report user & name
+			reportByName = path;
+		}
+	};
+
+	const experimentPath = () => `${prefix}${experimentSegment}`;
+	const blockPath = () => `${prefix}${blockSegment}`;
+	const databasePath = () => `${prefix}${databaseSegment}`;
+	const apiPath = () => `${prefix}${apiSegment}`;
+
+	const getExperimentUrl = (experimentName) => `${experimentPath()}${experimentName}/`;
+	const getBlockUrl = (blockName) => `${blockPath()}${expName}/`;
+	const getDatabaseUrl = (databaseName) => `${databasePath()}${databaseName}/`;
+	const getApiUrl = (apiSubpath) => `${apiPath()}${apiSubpath}`;
+
+	const getCompileRstUrl = () => `${getApiUrl(`${reportByName}rst/`)}`;
+
+	extractUsingCurrentUrl();
+
+	return {
+		getExperimentUrl,
+		getBlockUrl,
+		getDatabaseUrl,
+		getCompileRstUrl
+	};
+}]);
diff --git a/beat/web/reports/templates/reports/report.html b/beat/web/reports/templates/reports/report.html
index 2a4119abe6b0d99590cb79269192d743409a059c..881a92421462aeb2e7f67b4a4e19abc2d125b531 100644
--- a/beat/web/reports/templates/reports/report.html
+++ b/beat/web/reports/templates/reports/report.html
@@ -88,6 +88,7 @@
     <!-- services -->
     <script src="{% fingerprint "reports/app/services/groupsService.js" %}" type="text/javascript" charset="utf-8"></script>
     <script src="{% fingerprint "reports/app/services/experimentsService.js" %}" type="text/javascript" charset="utf-8"></script>
+    <script src="{% fingerprint "reports/app/services/urlService.js" %}" type="text/javascript" charset="utf-8"></script>
 
     <!-- directives
     -->