diff --git a/src/client/actions/index.js b/src/client/actions/index.js
index 14e610fe39364a64a32e30d0955b749339477311..fdd7e7fcb862a74c588ada55c1fdcc2e8affc1ca 100644
--- a/src/client/actions/index.js
+++ b/src/client/actions/index.js
@@ -102,8 +102,9 @@ export const fetchResultsFailed = (error) => ({
 });
 
 // Manuscripts
-export const fetchManuscripts = () => ({
+export const fetchManuscripts = (page) => ({
   type: FETCH_MANUSCRIPTS,
+  page
 });
 
 export const updateManuscripts = ({ manuscripts }) => ({
diff --git a/src/client/components/TopBar.js b/src/client/components/TopBar.js
index af75db7f6c06d19b5dd245be2da0e7ad792a177d..4e2d74e8c92a119d182aa966511c42512f935677 100644
--- a/src/client/components/TopBar.js
+++ b/src/client/components/TopBar.js
@@ -68,7 +68,7 @@ class TopBar extends React.Component {
   };
 
   componentDidMount() {
-    this.props.fetchManuscripts();
+    this.props.fetchManuscripts(1);
   }
 
   handleClick = event => {
diff --git a/src/client/epics/index.js b/src/client/epics/index.js
index a6344d0a182201196c6e20809a7e15e8ea949ea6..4c4428f045253fe37a8b57a102896abd45f0019d 100644
--- a/src/client/epics/index.js
+++ b/src/client/epics/index.js
@@ -72,13 +72,11 @@ const getSuggestionsEpic = (action$, store) => {
 //     });
 // };
 
-const getManuscripts = (action$, store) => {
+const getManuscripts = (action$) => {
   const searchUrl = hiplaApiUrl + 'manuscripts';
   return action$.ofType(FETCH_MANUSCRIPTS)
-    .switchMap(() => {
-      const { datasets } = store.getState().search;
-      const dsParams = _.map(pickSelectedDatasets(datasets), ds => `dataset=${ds}`).join('&');
-      const requestUrl = `${searchUrl}?${dsParams}`;
+    .switchMap(action => {
+      const requestUrl = `${searchUrl}?page=${action.page}`;
       return ajax.getJSON(requestUrl)
         .map(response => updateManuscripts({ manuscripts: response }))
         .catch(error => Observable.of({
diff --git a/src/server/index.js b/src/server/index.js
index 4ef3bdc9b5c9548400935f7e09d1b8671fb4fec3..7125eef3b6727a3c97ef06dfbb249bfccb707ebd 100644
--- a/src/server/index.js
+++ b/src/server/index.js
@@ -2,7 +2,7 @@ import express from 'express';
 import bodyParser from 'body-parser';
 import request from 'superagent';
 import _ from 'lodash';
-import sparqlSearchEngine from './sparql/SparqlSearchEngine';
+import { getManuscripts, getPlaces } from './sparql/Manuscripts';
 const DEFAULT_PORT = 3001;
 const app = express();
 //const isDevelopment  = app.get('env') !== 'production';
@@ -19,44 +19,10 @@ app.use(function(req, res, next) {
 
 app.use(express.static(__dirname + './../public/'));
 
-app.get('/suggest', (req, res) => {
-  // https://softwareengineering.stackexchange.com/questions/233164/how-do-searches-fit-into-a-restful-interface
-  // example request: http://localhost:3000/search?dataset=warsa_karelian_places&dataset=pnr&q=viip
-  const queryDatasets = _.castArray(req.query.dataset);
-  const queryTerm = req.query.q;
-  // console.log(queryDatasets);
-
-  return sparqlSearchEngine.getFederatedSuggestions(queryTerm, queryDatasets).then((data) => {
-    // console.log(data);
-    res.json(data);
-  })
-    .catch((err) => {
-      console.log(err);
-      return res.sendStatus(500);
-    });
-});
-
-app.get('/search', (req, res) => {
-  // https://softwareengineering.stackexchange.com/questions/233164/how-do-searches-fit-into-a-restful-interface
-  // example request: http://localhost:3000/search?dataset=warsa_karelian_places&dataset=pnr&q=viip
-  const queryDatasets = _.castArray(req.query.dataset);
-  const queryTerm = req.query.q;
-  // console.log(queryDatasets);
-
-  return sparqlSearchEngine.getFederatedResults(queryTerm, queryDatasets).then((data) => {
-    // console.log(data);
-    res.json(data);
-  })
-    .catch((err) => {
-      console.log(err);
-      return res.sendStatus(500);
-    });
-});
 
 app.get('/manuscripts', (req, res) => {
-  const queryDatasets = _.castArray(req.query.dataset);
-
-  return sparqlSearchEngine.getFederatedManuscripts(queryDatasets).then((data) => {
+  const page = req.query.page || 1;
+  return getManuscripts(page).then((data) => {
     // console.log(data);
     res.json(data);
   })
@@ -67,9 +33,7 @@ app.get('/manuscripts', (req, res) => {
 });
 
 app.get('/places', (req, res) => {
-  const queryDatasets = _.castArray(req.query.dataset);
-
-  return sparqlSearchEngine.getFederatedPlaces(queryDatasets).then((data) => {
+  return getPlaces().then((data) => {
     // console.log(data);
     res.json(data);
   })
diff --git a/src/server/sparql/Datasets.js b/src/server/sparql/Datasets.js
index 3613f4cfee5427d4efdce2130b7b857b31fbedf1..833937c8e0d633d2d554c4c973e24125aad24857 100644
--- a/src/server/sparql/Datasets.js
+++ b/src/server/sparql/Datasets.js
@@ -63,6 +63,7 @@ module.exports = {
       }
       GROUP BY ?id ?manuscriptRecord
       ORDER BY (!BOUND(?creationPlace)) ?creationPlace
+      <PAGE>
       `,
     'placeQuery': `
       PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
diff --git a/src/server/sparql/Manuscripts.js b/src/server/sparql/Manuscripts.js
new file mode 100644
index 0000000000000000000000000000000000000000..f12febfccec0ff943de9699008561ddcbda6dd21
--- /dev/null
+++ b/src/server/sparql/Manuscripts.js
@@ -0,0 +1,73 @@
+import SparqlSearchEngine from './SparqlSearchEngine';
+import datasetConfig from './Datasets';
+import {
+  mapPlaces,
+  mapManuscripts
+} from './Mappers';
+
+const sparqlSearchEngine = new SparqlSearchEngine();
+
+export const getManuscripts = (page) => {
+  let { endpoint, allQuery } = datasetConfig['mmm'];
+  allQuery = allQuery.replace('<PAGE>', 'LIMIT 25');
+  return sparqlSearchEngine.doSearch(allQuery, endpoint, mapManuscripts);
+};
+
+export const getPlaces = () => {
+  const { endpoint, placeQuery } = datasetConfig['mmm'];
+  return sparqlSearchEngine.doSearch(placeQuery, endpoint, mapPlaces);
+};
+
+
+const facetQuery = `
+  PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
+  PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+  PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
+  PREFIX crm: <http://www.cidoc-crm.org/cidoc-crm/>
+  PREFIX owl: <http://www.w3.org/2002/07/owl#>
+  PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
+  PREFIX text: <http://jena.apache.org/text#>
+  PREFIX dct: <http://purl.org/dc/terms/>
+  PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
+  PREFIX sch: <http://schema.org/>
+  PREFIX geosparql: <http://www.opengis.net/ont/geosparql#>
+  PREFIX frbroo: <http://erlangen-crm.org/efrbroo/>
+  SELECT DISTINCT ?cnt ?facet_text ?value
+  WHERE {
+    {
+      { SELECT DISTINCT (count(DISTINCT ?id) as ?cnt) {
+          ?id a frbroo:F4_Manifestation_Singleton .
+          ?id skos:prefLabel ?name .
+        }
+      } BIND("-- Ei valintaa --" AS ?facet_text) }
+    UNION
+    {
+      SELECT DISTINCT ?cnt ?value ?facet_text {
+        { SELECT DISTINCT (count(DISTINCT ?id) as ?cnt) ?value {
+            ?id a frbroo:F4_Manifestation_Singleton .
+            ?id skos:prefLabel ?name .
+            ?id ^frbroo:R18_created/crm:P7_took_place_at ?value .
+          }
+          GROUP BY ?value
+        }
+        FILTER(BOUND(?value)) BIND(COALESCE(?value, <http://ldf.fi/NONEXISTENT_URI>) AS ?labelValue)
+        OPTIONAL { ?labelValue skos:prefLabel ?lbl .
+          FILTER(langMatches(lang(?lbl), "fi")) . }
+        OPTIONAL { ?labelValue rdfs:label ?lbl .
+          FILTER(langMatches(lang(?lbl), "fi")) . }
+        OPTIONAL { ?labelValue skos:prefLabel ?lbl .
+          FILTER(langMatches(lang(?lbl), "en")) . }
+        OPTIONAL { ?labelValue rdfs:label ?lbl .
+          FILTER(langMatches(lang(?lbl), "en")) . }
+        OPTIONAL { ?labelValue skos:prefLabel ?lbl .
+          FILTER(langMatches(lang(?lbl), "sv")) . }
+        OPTIONAL { ?labelValue rdfs:label ?lbl .
+          FILTER(langMatches(lang(?lbl), "sv")) . }
+        OPTIONAL { ?labelValue skos:prefLabel ?lbl .
+          FILTER(langMatches(lang(?lbl), "")) . }
+        OPTIONAL { ?labelValue rdfs:label ?lbl .
+          FILTER(langMatches(lang(?lbl), "")) . }
+        BIND(COALESCE(?lbl, IF(!ISURI(?value), ?value, "")) AS ?facet_text) }
+    }
+  }
+`;
diff --git a/src/server/sparql/SparqlSearchEngine.js b/src/server/sparql/SparqlSearchEngine.js
index 4d4233312f2c8801bfa3c5a3cac36c2397c933e4..e49c217dd21ba1d2ef004421244f80fa280ea811 100644
--- a/src/server/sparql/SparqlSearchEngine.js
+++ b/src/server/sparql/SparqlSearchEngine.js
@@ -1,12 +1,5 @@
 import _ from 'lodash';
 import SparqlApi from './SparqlApi';
-import datasetConfig from './Datasets';
-import {
-  mergeFederatedResults,
-  mapPlaces,
-  mapManuscripts
-} from './Mappers';
-//import { makeObjectList } from './SparqlObjectMapper';
 
 class SparqlSearchEngine {
 
@@ -21,67 +14,6 @@ class SparqlSearchEngine {
       });
   }
 
-  getAllManuscripts(datasetId) {
-    const { endpoint, allQuery } = datasetConfig[datasetId];
-    return this.doSearch(allQuery, endpoint, mapManuscripts);
-  }
-
-  getAllPlaces(datasetId) {
-    const { endpoint, placeQuery } = datasetConfig[datasetId];
-    // console.log(allQuery)
-    return this.doSearch(placeQuery, endpoint, mapPlaces);
-  }
-
-  getFederatedManuscripts(datasets) {
-    return Promise.all(datasets.map((datasetId) =>
-      this.getAllManuscripts(datasetId)))
-      .then(mergeFederatedResults);
-    // .then((manuscripts) => this.getPlaces(manuscripts));
-  }
-
-  getFederatedPlaces(datasets) {
-    return Promise.all(datasets.map((datasetId) =>
-      this.getAllPlaces(datasetId)))
-      .then(mergeFederatedResults);
-    // .then((manuscripts) => this.getPlaces(manuscripts));
-  }
-
-
-  //
-  // getPlaces(manuscripts) {
-  //   const { endpoint, placeQuery } = datasetConfig.mmm;
-  //   let placeIds = manuscripts.reduce((places, manuscript) => {
-  //     if (manuscript.creationPlace !== undefined) {
-  //       const creationPlaceArr = manuscript.creationPlace.split(',');
-  //       places = places.concat(creationPlaceArr);
-  //     }
-  //     return places;
-  //   }, []);
-  //   placeIds = Array.from(new Set(placeIds)); //remove duplicates
-  //   return this.doSearch(placeQuery.replace('<ID>', this.uriFy(placeIds)), endpoint, makeDict)
-  //     .then((placeDict) => {
-  //       manuscripts.map((manuscript) => {
-  //         if (manuscript.creationPlace !== undefined) {
-  //           let creationPlaceObjs;
-  //           const creationPlaceArr = manuscript.creationPlace.split(',');
-  //           if (creationPlaceArr.length > 1) {
-  //             creationPlaceObjs = creationPlaceArr.map((place) => {
-  //               return placeDict[place];
-  //             });
-  //           } else {
-  //             creationPlaceObjs = placeDict[creationPlaceArr[0]];
-  //           }
-  //           manuscript.creationPlace = creationPlaceObjs;
-  //           return manuscript;
-  //         }
-  //       });
-  //       return {
-  //         'manuscripts': manuscripts,
-  //         'creationPlaces': placeDict
-  //       };
-  //     });
-  // }
-
   uriFy(id) {
     if (_.isArray(id)) {
       return '<' + id.join('> <') + '>';
@@ -92,4 +24,4 @@ class SparqlSearchEngine {
   }
 }
 
-export default new SparqlSearchEngine();
+export default SparqlSearchEngine;