diff --git a/src/components/OcTopMenu.vue b/src/components/OcTopMenu.vue
index ffc954455a853dbd6cfff16be3e445b09e273ea9..ac4e5c4d1540989aa04f08235ad8910e6b0e5a0d 100644
--- a/src/components/OcTopMenu.vue
+++ b/src/components/OcTopMenu.vue
@@ -49,7 +49,8 @@ const menuItems = computed(() => {
           params: {
             ...route.params,
             lang: key
-          }
+          },
+          query: route.query
         })
       }
     })
diff --git a/src/pages/community/[community].search.vue b/src/pages/community/[community].search.vue
index 4b383704ecfe447e4e844547cde8530e8363dd90..7fa863df82776976f960987e4b490cf38825c16d 100644
--- a/src/pages/community/[community].search.vue
+++ b/src/pages/community/[community].search.vue
@@ -5,16 +5,30 @@
   >
     <div class="flex flex-row">
       <div class="p-4 pl-8 w-2/12 ml-auto mr-auto">
-        <Panel :header="t('search.resourceType')" toggleable>
-          <template #toggleicon="toggleIconProps">
-            <i v-if="toggleIconProps.collapsed" class="fa-solid fa-chevron-down text-gray-700"/>
-            <i v-else class="fa-solid fa-chevron-up text-gray-700"/>
-          </template>
-          <div class="flex items-center gap-2" v-for="(dcatType, uri) in type2ResourceType" v-bind:key="uri">
-            <Checkbox v-model="resourceType" :inputId="uri" name="resourceType" :value="uri" />
-            <label for="resourceType" class="capitalize"> {{ t('resourceType.'+dcatType) }} </label>
-          </div>
-        </Panel>
+        <form id="searchForm" method="get" ref="searchForm" v-on:submit="submit">
+          <Panel :header="t('search.resourceType')" toggleable>
+            <template #toggleicon="toggleIconProps">
+              <i v-if="toggleIconProps.collapsed" class="fa-solid fa-chevron-down text-gray-700" />
+              <i v-else class="fa-solid fa-chevron-up text-gray-700" />
+            </template>
+            <div
+              class="flex items-center gap-2"
+              v-for="(dcatType, uri) in type2ResourceType"
+              v-bind:key="uri"
+            >
+              <Checkbox
+                v-model="resourceType"
+                :inputId="uri"
+                name="resourceType"
+                :value="uri"
+                @change="submit"
+              />
+              <label for="resourceType" class="capitalize">
+                {{ t('resourceType.' + dcatType) }}
+              </label>
+            </div>
+          </Panel>
+        </form>
       </div>
       <div class="p-4 pl-8 w-9/12 ml-auto mr-auto">
         <h1 class="font-title text-4xl uppercase font-bold mb-4 text-primary">
@@ -23,12 +37,13 @@
         <IconField class="w-full mt-8 mb-4">
           <InputText
             id="search"
+            form="searchForm"
             v-model="queryString"
             fluid
             size="large"
             :placeholder="t('community.homepage.searchBarPlaceholder')"
           />
-          <InputIcon class="fa-solid fa-magnifying-glass" :onclick="search" />
+          <InputIcon class="fa-solid fa-magnifying-glass" :onclick="submit" />
         </IconField>
         <div v-if="!searching">
           <template v-for="result in searchResultObjects" v-bind:key="result">
@@ -44,11 +59,11 @@
         </div>
         <Paginator
           class="mt-8"
-          always-show="false"
+          :always-show="false"
           :rows="itemsPerPage"
+          v-model:first="start"
           :total-records="searchResultList.length"
-          v-bind:currentPage="currentPage"
-          v-on:page="getResultsForPage($event.page)"
+          v-on:page="submit"
         />
       </div>
     </div>
@@ -62,7 +77,7 @@ import { useCommunityData } from '@/dataLoaders/community'
 import type { OcBreadcrumbItem, OcSearchResult } from '@/declarations'
 import OcLayoutSimple from '@/layout/OcLayoutSimple/OcLayoutSimple.vue'
 import { useAccountStore } from '@/stores/account'
-import { computed, ref } from 'vue'
+import { computed, onBeforeMount, ref, watch } from 'vue'
 import { useI18n } from 'vue-i18n'
 import IconField from 'primevue/iconfield'
 import InputText from 'primevue/inputtext'
@@ -74,6 +89,7 @@ import Paginator from 'primevue/paginator'
 import Panel from 'primevue/panel'
 import Checkbox from 'primevue/checkbox'
 import { type2ResourceType } from '@/helpers/resourceType'
+import { useRoute, useRouter } from 'vue-router'
 
 definePage({
   name: 'community.search',
@@ -84,17 +100,20 @@ definePage({
 })
 
 const accountStore = useAccountStore()
-const { t } = useI18n()
+const { locale, t } = useI18n()
 
 const { translateValue } = useTranslateValue()
 
 const { data: community } = useCommunityData()
 
+const route = useRoute()
+const router = useRouter()
+
 const itemsPerPage = 5
-const currentPage = ref(0)
+const start = ref(route.query.start ?? 0)
 
-const queryString = ref('')
-const resourceType = ref([])
+const queryString = ref(route.query.q)
+const resourceType = ref(route.query.type)
 
 const searchResultList = ref<string[]>([])
 const searchResultObjects = ref<OcSearchResult[]>([])
@@ -102,13 +121,28 @@ const searchResultObjects = ref<OcSearchResult[]>([])
 const searching = ref(false)
 const errorMessage = ref<string | null>(null)
 
+const submit = () => {
+  router.push({
+    name: "community.search",
+    params: {
+      lang: locale.value,
+      community: community.value.name
+    },
+    query: {
+      q: queryString.value,
+      type: resourceType.value,
+      start: start.value
+    }
+  })
+}
+
 const search = async () => {
   if (searching.value) {
     return
   }
 
   searching.value = true
-  currentPage.value = 0
+  start.value = 0
   try {
     searchResultList.value = await searchResources(
       {
@@ -122,31 +156,28 @@ const search = async () => {
     errorMessage.value = (e as Error).message ?? 'Error'
   }
 
-  try {
-    searchResultObjects.value = await getSearchResults(
-      searchResultList.value.slice(0, itemsPerPage),
-      accountStore.auth
-    )
-  } catch (e) {
-    console.error(e)
-    errorMessage.value = (e as Error).message ?? 'Error'
-  }
+  getResultsForStart(start.value)
 
   searching.value = false
 }
 
-const getResultsForPage = async (pagenumber: number) => {
-  searching.value = true
-  try {
-    searchResultObjects.value = await getSearchResults(
-      searchResultList.value.slice(pagenumber * itemsPerPage, (pagenumber + 1) * itemsPerPage),
-      accountStore.auth
-    )
-  } catch (e) {
-    console.error(e)
-    errorMessage.value = (e as Error).message ?? 'Error'
+const getResultsForStart = async (start: number) => {
+  const resourceUriList = searchResultList.value.slice(start, start + itemsPerPage)
+  if (resourceUriList.length){
+    searching.value = true
+    try {
+      searchResultObjects.value = await getSearchResults(
+        resourceUriList,
+        accountStore.auth
+      )
+    } catch (e) {
+      console.error(e)
+      errorMessage.value = (e as Error).message ?? 'Error'
+    }
+    searching.value = false
+  } else {
+    console.log("No results")
   }
-  searching.value = false
 }
 
 const breadcrumbItems = computed<OcBreadcrumbItem[]>(() => [
@@ -162,13 +193,37 @@ const breadcrumbItems = computed<OcBreadcrumbItem[]>(() => [
     type: 'search'
   }
 ])
+
+watch(
+  () => route.query,
+  (newQuery, oldQuery) => {
+    if (newQuery.q != oldQuery.q || newQuery.type != oldQuery.type){
+      start.value = parseInt(newQuery.start) ?? 0
+      getResultsForStart(start.value)
+    }
+    else {
+      start.value = 0
+      search()
+    }
+  }
+)
+
+onBeforeMount(() => {
+  if (route.query.q || route.query.type){
+    queryString.value = route.query.q as string ?? ""
+    resourceType.value = route.query.type as string[] ?? []
+    start.value = parseInt(route.query.start as string) ?? 0
+    search()
+  }
+})
 </script>
+
 <style scoped>
 :deep(.p-panel-header) {
-  @apply bg-primary rounded-t text-white mb-2
+  @apply bg-primary rounded-t text-white mb-2;
 }
 
-:deep(.p-panel){
-  @apply bg-gray-100
+:deep(.p-panel) {
+  @apply bg-gray-100;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/pages/community/[community]/index.vue b/src/pages/community/[community]/index.vue
index 7177e849b3dc9a933e75e68a301447fe70d82f54..fb976153fa52bd003edc562b3a64ccc5332b8b9a 100644
--- a/src/pages/community/[community]/index.vue
+++ b/src/pages/community/[community]/index.vue
@@ -22,15 +22,19 @@
         {{ t('community.homepage.searchBarLegend') }}
       </h3>
 
+      <form v-on:submit="search">
       <IconField class="w-full mt-4 mb-4">
-        <InputText
-          id="search"
-          fluid
-          size="large"
-          :placeholder="t('community.homepage.searchBarPlaceholder')"
-        />
-        <InputIcon class="fa-solid fa-magnifying-glass" />
-      </IconField>
+          <InputText
+            id="search"
+            v-model="queryString"
+            fluid
+            size="large"
+            :placeholder="t('community.homepage.searchBarPlaceholder')"
+          />
+          <InputIcon class="fa-solid fa-magnifying-glass" @click="search"/>
+        </IconField>
+    </form>
+
     </section>
 
     <section
@@ -71,7 +75,7 @@
 </template>
 
 <script setup lang="ts">
-import { computed } from 'vue'
+import { computed, ref } from 'vue'
 import { useAccountStore } from '@/stores/account'
 import { useI18n } from 'vue-i18n'
 import { useTranslateValue } from '@/composables/useTranslateValue'
@@ -85,6 +89,7 @@ import { getColor } from '@/helpers/communityColor'
 import { useCommunityData } from '@/dataLoaders/community'
 import { useTreeStore } from '@/stores/tree'
 import { useAbility } from '@casl/vue'
+import { useRouter } from 'vue-router'
 
 definePage({
   name: 'community',
@@ -98,9 +103,10 @@ treeStore.state.selectedNodeKey = undefined
 
 const { data: community } = useCommunityData()
 
-const { t } = useI18n()
+const { locale, t } = useI18n()
 const { translateValue } = useTranslateValue()
 const { cannot } = useAbility()
+const router = useRouter()
 
 const account = useAccountStore()
 
@@ -108,4 +114,24 @@ const title = computed(() => translateValue(community.value?.title))
 const abstract = computed(() => translateValue(community.value?.abstract))
 const logoUrl = computed(() => community.value?.logo ?? null)
 const color = computed(() => getColor(community.value))
+
+const isMemberOfCurrentCommunity = computed(
+  () => community.value?.['@id'] && memberCommunitiesList.value.includes(community.value?.['@id'])
+)
+
+const queryString = ref('')
+
+const search = () => {
+  router.push({
+    name: 'community.search',
+    params: {
+      lang: locale.value,
+      community: community.value.name,
+    },
+    query: {
+      q: queryString.value,
+      start: 0
+    }
+  })
+}
 </script>
diff --git a/src/sparql/search.ts b/src/sparql/search.ts
index 04e66d9dd7beb84cc352f6d4feb7cfea3f3f1959..5918bc9254939a5e8f7e603a53d8b734f22c47e0 100644
--- a/src/sparql/search.ts
+++ b/src/sparql/search.ts
@@ -7,34 +7,36 @@ import { resourceContext } from './resource'
  * Get results URI of a search query
  */
 export const searchResources = async (query: OcSearchQuery, auth?: Credentials) => {
-  let typeFilter = ""
-  if (query.resourceType?.length){
-    typeFilter = "FILTER (?type = <"
+  let typeFilter = ''
+  if (query.resourceType?.length) {
+    typeFilter = 'FILTER (?type = <'
     typeFilter += query.resourceType.join('> || ?type = <')
-    typeFilter += ">)"
+    typeFilter += '>)'
   }
 
-  let queryFilter = ""
-  if (query.queryString){
+  let queryFilter = ''
+  if (query.queryString) {
     queryFilter = `FILTER regex(?o, "${query.queryString}", "i")`
   }
 
-  const res =  await executeSparqlSelect(
-  `
+  const res = await executeSparqlSelect(
+    `
       SELECT DISTINCT ?resource
       WHERE {
         ?resource rdf:type ?type.
+        ?resource dct:identifier ?identifier.
         ${typeFilter}
         FILTER EXISTS {
           VALUES ?p { dct:title dct:description }
           ?resource ?p ?o
           ${queryFilter}
         }
-      }
+      } ORDER BY ASC(?identifier)
     `,
-  {
-    auth: auth,
-  })
+    {
+      auth: auth
+    }
+  )
 
   return res.map((result) => result.resource.value)
 }
@@ -42,7 +44,25 @@ export const searchResources = async (query: OcSearchQuery, auth?: Credentials)
 /** Get searchResults objects from URI list */
 export const getSearchResults = async (resourceUriList: string[], auth?: Credentials) => {
   const searchResultContext: ContextDefinition = {
-    ...resourceContext,
+    '@type': {
+      '@container': '@set'
+    },
+    identifier: {
+      '@id': 'http://purl.org/dc/terms/identifier'
+    },
+    title: {
+      '@id': 'http://purl.org/dc/terms/title',
+      '@container': '@language'
+    },
+    description: {
+      '@id': 'http://purl.org/dc/terms/description',
+      '@container': '@language'
+    },
+    graph: {
+      '@id': 'https://www.irit.fr/opencommon/terms/graph',
+      '@type': '@id',
+      '@container': ['@set']
+    },
     catalog: {
       '@id': 'http://www.w3.org/ns/dcat#catalog',
       '@type': '@id',
@@ -57,17 +77,17 @@ export const getSearchResults = async (resourceUriList: string[], auth?: Credent
       '@id': 'http://www.w3.org/ns/dcat#distribution',
       '@type': '@id',
       '@container': '@set'
-    },
+    }
   }
 
   const formattedUris = '<' + resourceUriList.join('> <') + '>'
 
   return await executeSparqlConstruct<OcSearchResult>(
-  `
+    `
       CONSTRUCT {
         ?s ?p ?o.
         ?s oct:graph ?g.
-        ?s dcat:dataset ?dataset
+        ?s dct:identifier ?identifier.
       }
       WHERE {
         VALUES ?s { ${formattedUris} }
@@ -88,8 +108,9 @@ export const getSearchResults = async (resourceUriList: string[], auth?: Credent
         }
       }
     `,
-  {
-    context: searchResultContext,
-    auth: auth,
-  })
-}
\ No newline at end of file
+    {
+      context: searchResultContext,
+      auth: auth
+    }
+  )
+}
diff --git a/typed-router.d.ts b/typed-router.d.ts
index bb4d634acc9ccb77c5f192111635049f9d9c8bec..341f99c91b3177ba85a913ec72f0fd89449e089a 100644
--- a/typed-router.d.ts
+++ b/typed-router.d.ts
@@ -30,7 +30,7 @@ declare module 'vue-router/auto-routes' {
     'community.dashboard.dataset': RouteRecordInfo<'community.dashboard.dataset', '/:lang/community/:community/dashboard/dataset', { community: ParamValue<true> }, { community: ParamValue<false> }>,
     'community.datasets.new': RouteRecordInfo<'community.datasets.new', '/:lang/community/:community/dataset/new', { community: ParamValue<true> }, { community: ParamValue<false> }>,
     'community.join': RouteRecordInfo<'community.join', '/:lang/community/:community/join', { community: ParamValue<true> }, { community: ParamValue<false> }>,
-    '/:lang/community/[community].search': RouteRecordInfo<'/:lang/community/[community].search', '/:lang/community/:community/search', { community: ParamValue<true> }, { community: ParamValue<false> }>,
+    'community.search': RouteRecordInfo<'community.search', '/:lang/community/:community/search', { community: ParamValue<true> }, { community: ParamValue<false> }>,
     'connection': RouteRecordInfo<'connection', '/:lang/connection', Record<never, never>, Record<never, never>>,
     'logout': RouteRecordInfo<'logout', '/:lang/logout', Record<never, never>, Record<never, never>>,
     'profile': RouteRecordInfo<'profile', '/:lang/profile', Record<never, never>, Record<never, never>>,