diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4ef6f7f43d6ef023e19dadd3355c43ab62b0daf1..a10231ea23ba3c07571272679828cc8226abd1ce 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -37,11 +37,15 @@ deploy_dev:
 test:
   stage: test
   image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/node:14.15.4
+  services:
+    - name: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/elasticsearch:7.16.2
+      alias: elasticsearch
+      command: ['bin/elasticsearch', '-Expack.security.enabled=false', '-Ediscovery.type=single-node']
   before_script:
     - export GHOST_HOST_AND_PORT=http://localhost:2368
     - export GHOST_ADMIN_API_KEY=60142bc9e33940000156bccc:6217742e2671e322612e89cac9bab61fcd01822709fe5d8f5e6a5b3e54d5e6bb
     - export SALT=$TEST_SALT
-    - export ELASTICSEARCH_NODE=http://localhost:9200
+    - export ELASTICSEARCH_NODE=http://elasticsearch:9200
   script:
     - npm i
     - npm run test:cov
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d0283d21d5b1189a6a3b1bf6e3177049f59cc333..f7144aeed55f2a57e64dc6cfa664937f3bdeec8f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,15 @@
 
 All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
 
+## [1.13.0](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v1.12.0...v1.13.0) (2022-02-07)
+
+
+### Features
+
+* **pages:** display pages from ghost (eg. : about page and accessibility page) ([e4096e8](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/e4096e89266fb1c206089f739c0d2bcb15ad69c6))
+* **routing:** update global routing of api ([f7fd011](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/f7fd0113461879bc10fabb2ab51d07551342e906))
+* **search:** search-improvement ([fbbf2fb](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/fbbf2fb6142d879bad296c104c1e4da42e93dc3a))
+
 ## [1.12.0](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v1.11.0...v1.12.0) (2022-02-01)
 
 
diff --git a/package-lock.json b/package-lock.json
index 68a82b54fe27f5e47491b9eb6f2331fead4b4646..5fa86577d523253df5e0dfc6867adc25e052aa6f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "ram_server",
-  "version": "1.12.0",
+  "version": "1.13.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
diff --git a/package.json b/package.json
index 6ed806505489881389d5a3b7c55d09f169f2f6e4..f5d07a96b7b158ae81643f42d291f17ca5d7e51b 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "ram_server",
   "private": true,
-  "version": "1.12.0",
+  "version": "1.13.0",
   "description": "Nest TypeScript starter repository",
   "license": "MIT",
   "scripts": {
diff --git a/scripts/ghost/migrations/init/pages.json b/scripts/ghost/migrations/init/pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..08e28b9cdbfa93af79287f7302eab207b85cfa8d
--- /dev/null
+++ b/scripts/ghost/migrations/init/pages.json
@@ -0,0 +1,61 @@
+[
+  {
+    "slug": "qui-sommes-nous",
+    "id": "61efc44b26db9e00015c4f32",
+    "title": "Qui sommes-nous ?",
+    "html": "<p>La numérisation accélérée des différents services privés et publics ainsi que la crise sanitaire que nous traversons a renforcé une fracture numérique déjà forte pour un nombre important de citoyens.</p><p>Au printemps 2019, la Métropole de Lyon s'est saisie des enjeux autour de l'inclusion numérique en initiant la structuration d'un réseau des acteurs de la médiation numérique sur son territoire. Son objectif est de mettre en relation les acteurs qui œuvrent au quotidien pour limiter cette fracture numérique, nombreux sur le territoire de la Métropole : associations, centres sociaux, structures informations jeunesses, grands opérateurs de services publics, collectivités...</p><p>Des ateliers de travail ont été organisés en 2019 pour identifier les besoins de ces acteurs et 9 offres de services ont été identifiées :</p><h3 id=\"recenser-et-partager-des-ressources-existantes-optimisation\">Recenser et partager des ressources existantes (optimisation)</h3><figure class=\"kg-card kg-image-card\"><img src=\"http://localhost:4200/assets/img/about_illustration_1.jpg\" class=\"kg-image\" alt=\"illustration des besoins\" loading=\"lazy\"></figure><h3 id=\"co-construire-de-nouvelles-ressources-d%C3%A9veloppement\">Co-construire de nouvelles ressources (développement)</h3><figure class=\"kg-card kg-image-card\"><img src=\"http://localhost:4200/assets/img/about_illustration_2.jpg\" class=\"kg-image\" alt=\"illustration des besoins\" loading=\"lazy\"></figure><p>Cet espace vise à centraliser et mettre en commun les ressources développées dans le cadre du réseau par ses acteurs.</p><p>N'hésitez pas à contribuer à cet espace en partageant vos ressources</p><!--kg-card-begin: markdown--><div style=\"display:flex; margin:0;padding:5px;align-items:center;\"\n</div><!--kg-card-end: markdown--><figure class=\"kg-card kg-image-card\"><img src=\"http://localhost:2368/content/images/2022/01/logo_europe.png\" class=\"kg-image\" alt loading=\"lazy\"></figure><figure class=\"kg-card kg-image-card\"><img src=\"http://localhost:2368/content/images/2022/01/logo_region.png\" class=\"kg-image\" alt=\"logo de l'union européenne\" loading=\"lazy\" width=\"220\" height=\"98\"></figure>",
+    "feature_image": null,
+    "featured": false,
+    "visibility": "public",
+    "created_at": "2022-01-25T09:35:07.000+00:00",
+    "updated_at": "2022-01-25T09:35:07.000+00:00",
+    "published_at": "2022-01-25T09:35:07.000+00:00",
+    "status": "published",
+    "custom_excerpt": null,
+    "codeinjection_head": null,
+    "codeinjection_foot": null,
+    "custom_template": null,
+    "canonical_url": null,
+    "url": "http://localhost:2368/qui-sommes-nous/",
+    "excerpt": "La numérisation accélérée des différents services privés et publics ainsi que la\ncrise sanitaire que nous traversons a renforcé une fracture numérique déjà forte\npour un nombre important de citoyens.\n\nAu printemps 2019, la Métropole de Lyon s'est saisie des enjeux autour de\nl'inclusion numérique en initiant la structuration d'un réseau des acteurs de la\nmédiation numérique sur son territoire. Son objectif est de mettre en relation\nles acteurs qui œuvrent au quotidien pour limiter cette fracture ",
+    "page": true,
+    "og_image": null,
+    "og_title": null,
+    "og_description": null,
+    "twitter_image": null,
+    "twitter_title": null,
+    "twitter_description": null,
+    "meta_title": null,
+    "meta_description": null,
+    "frontmatter": null
+  },
+  {
+    "slug": "accessibilite",
+    "id": "61effea226db9e00015c4f41",
+    "title": "Accessibilité",
+    "html": "<p>Page accessibilité. Contenu en cours de rédaction. </p>",
+    "feature_image": null,
+    "featured": false,
+    "visibility": "public",
+    "created_at": "2022-01-25T13:44:02.000+00:00",
+    "updated_at": "2022-01-25T13:44:02.000+00:00",
+    "published_at": "2022-01-25T13:44:02.000+00:00",
+    "status": "published",
+    "custom_excerpt": null,
+    "codeinjection_head": null,
+    "codeinjection_foot": null,
+    "custom_template": null,
+    "canonical_url": null,
+    "url": "http://localhost:2368/accessibilite/",
+    "excerpt": "Page accessibilité. Contenu a venir.",
+    "og_image": null,
+    "og_title": null,
+    "og_description": null,
+    "twitter_image": null,
+    "twitter_title": null,
+    "twitter_description": null,
+    "meta_title": null,
+    "meta_description": null,
+    "frontmatter": null
+  }
+]
diff --git a/scripts/init-ghost.js b/scripts/init-ghost.js
index 4ecc42cb5c8af6ff8afbcb25e2caebd34150efc0..8c0ba5feba09a5c3f1828d9dafcfaadef3fe91a0 100644
--- a/scripts/init-ghost.js
+++ b/scripts/init-ghost.js
@@ -5,6 +5,8 @@ const tagsData = require('./ghost/migrations/init/tags.json');
 // eslint-disable-next-line @typescript-eslint/no-var-requires
 const postsData = require('./ghost/migrations/init/posts.json');
 // eslint-disable-next-line @typescript-eslint/no-var-requires
+const pagesData = require('./ghost/migrations/init/pages.json');
+// eslint-disable-next-line @typescript-eslint/no-var-requires
 const path = require('path');
 // eslint-disable-next-line @typescript-eslint/no-var-requires
 const GhostAdminAPI = require('@tryghost/admin-api');
@@ -21,7 +23,7 @@ var api = new GhostAdminAPI({
 async function deleteTags(existingTags) {
   return await Promise.all(
     _.forEach(existingTags, async (tag) => {
-      api.tags
+      await api.tags
         .delete(_.pick(tag, ['id']))
         .then((res) => {
           return null;
@@ -33,7 +35,7 @@ async function deleteTags(existingTags) {
 async function deletePosts(existingPosts) {
   return await Promise.all(
     _.forEach(existingPosts, async (tag) => {
-      api.posts
+      await api.posts
         .delete(_.pick(tag, ['id']))
         .then((res) => {
           return null;
@@ -42,6 +44,18 @@ async function deletePosts(existingPosts) {
     })
   );
 }
+async function deletePages(existingPages) {
+  return await Promise.all(
+    _.forEach(existingPages, async (id) => {
+      await api.pages
+        .delete(_.pick(id, ['id']))
+        .then((res) => {
+          return null;
+        })
+        .catch((error) => console.error(error));
+    })
+  );
+}
 
 async function createTags(deleteOnly) {
   // Get existing tags
@@ -100,22 +114,22 @@ function processImagesInHTML(html) {
   });
 }
 
-async function uploadPostImage(imagePath)
-{
+async function uploadPostImage(imagePath) {
   let imagePromise = api.images.upload({
-      ref: imagePath,
-      file: path.resolve(imagePath)
-    });
+    ref: imagePath,
+    file: path.resolve(imagePath),
+  });
 
-    return Promise.resolve(imagePromise).then((url) => {
+  return Promise.resolve(imagePromise)
+    .then((url) => {
       return url.url;
-    }).catch((error) => {
-      console.error(error);
-      return null
     })
+    .catch((error) => {
+      console.error(error);
+      return null;
+    });
 }
 
-
 async function createPosts(deleteOnly) {
   api.posts
     .browse({ limit: 'all' })
@@ -152,10 +166,52 @@ async function createPosts(deleteOnly) {
     .catch((error) => console.error(error));
 }
 
+async function createPages(deleteOnly) {
+  api.pages
+    .browse({ limit: 'all' })
+    .then(async (existingPages) => {
+      // remove 'meta' key
+      delete existingPages['meta'];
+      if (existingPages.length > 0) {
+        console.log(`-- Dropping ${existingPages.length} pages... --`);
+        // Delete existing pages
+        await deletePages(existingPages).then(() => {
+          console.log('-- Pages dropped --');
+        });
+      } else {
+        console.log('-- No pages to drop --');
+      }
+      // wait complete delete of pages, if not page slugs are appended by _2
+      await new Promise((r) => setTimeout(r, 1000));
+
+      // Creating new pages
+      if (!deleteOnly) {
+        console.log(`-- Creating ${pagesData.length} pages --`);
+        _.forEach(pagesData, async (page) => {
+          //upload de l'image en featured_image
+          if (page.feature_image) {
+            page.feature_image = await uploadPostImage(page.feature_image);
+          }
+          api.pages
+            .add(page, { source: 'html' })
+            .then((res) => {
+              console.log(`-- Page \`${res.title}\` created --`);
+            })
+            .catch((error) => console.error(error));
+        });
+      }
+    })
+    .catch((error) => console.error(error));
+}
+
 async function main(deleteOnly) {
-  createTags(deleteOnly).then(() => {
-    createPosts(deleteOnly);
-  });
+  createTags(deleteOnly)
+    .then(() => {
+      createPosts(deleteOnly);
+    })
+    .then(() => {
+      createPages(deleteOnly);
+    });
 }
 
 var myArgs = process.argv.slice(2);
diff --git a/src/app.module.ts b/src/app.module.ts
index 96c38318fa9f1359ce29a6764d71da6acfafc27c..148e1d602021bffb847d7cb6c6d253f4fbfcee1a 100644
--- a/src/app.module.ts
+++ b/src/app.module.ts
@@ -11,6 +11,7 @@ import { MailerModule } from './mailer/mailer.module';
 import { TclModule } from './tcl/tcl.module';
 import { AdminModule } from './admin/admin.module';
 import { PostsModule } from './posts/posts.module';
+import { PagesModule } from './pages/pages.module';
 import { TempUserModule } from './temp-user/temp-user.module';
 import { NewsletterModule } from './newsletter/newsletter.module';
 import { ContactModule } from './contact/contact.module';
@@ -29,6 +30,7 @@ import { ContactModule } from './contact/contact.module';
     TclModule,
     AdminModule,
     PostsModule,
+    PagesModule,
     TempUserModule,
     NewsletterModule,
     ContactModule,
diff --git a/src/main.ts b/src/main.ts
index d4287f5015f44ad7e5e76f6ab93023cd41caf1d7..5f6620aa88a5e96980f4e3fb58039c8e0ded4bde 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -7,13 +7,14 @@ async function bootstrap() {
   const app = await NestFactory.create(AppModule);
   app.useGlobalPipes(new ValidationPipe());
   const options = new DocumentBuilder()
-    .setTitle('RAM')
-    .setDescription('RAM API description')
+    .setTitle(`Res'in`)
+    .setDescription(`Res'in API documentation`)
     .setVersion('1.0')
     .addBearerAuth({ type: 'http', scheme: 'bearer', bearerFormat: 'JWT' }, 'JWT')
     .build();
   const document = SwaggerModule.createDocument(app, options);
-  SwaggerModule.setup('api', app, document);
+  SwaggerModule.setup('doc', app, document);
+  app.setGlobalPrefix('api');
   await app.listen(3000);
 }
 bootstrap();
diff --git a/src/pages/pages.controller.spec.ts b/src/pages/pages.controller.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..da887e40ae3dc5e2a41bc4e5c27f07c18616354d
--- /dev/null
+++ b/src/pages/pages.controller.spec.ts
@@ -0,0 +1,91 @@
+import { HttpModule, HttpService } from '@nestjs/common';
+import { Test, TestingModule } from '@nestjs/testing';
+import { of } from 'rxjs';
+import { ConfigurationModule } from '../configuration/configuration.module';
+import { PagesController } from './pages.controller';
+import { AxiosResponse } from 'axios';
+
+describe('PagesController', () => {
+  let controller: PagesController;
+
+  const httpServiceMock = {
+    get: jest.fn(),
+  };
+  beforeEach(async () => {
+    const module: TestingModule = await Test.createTestingModule({
+      imports: [ConfigurationModule, HttpModule],
+      providers: [
+        {
+          provide: HttpService,
+          useValue: httpServiceMock,
+        },
+      ],
+      controllers: [PagesController],
+    }).compile();
+
+    controller = module.get<PagesController>(PagesController);
+  });
+
+  it('should be defined', () => {
+    expect(controller).toBeDefined();
+  });
+
+  describe('getPagebySlug', () => {
+    it('should get page Hello by Slug hello', async () => {
+      const data = [
+        {
+          id: '61c4847b0ff4550001505090',
+          uuid: 'f4ee5a37-a343-4cad-8a32-3f6cf87f9569',
+          title: 'Hello',
+          slug: 'hello',
+          html: '<p>Test</p>',
+          comment_id: '61c4847b0ff4550001505090',
+          feature_image: 'http://localhost:2368/content/images/2021/12/dacc-4.png',
+          featured: false,
+          visibility: 'public',
+          created_at: '2022-01-25T09:35:07.000+00:00',
+          updated_at: '2022-01-26T15:24:24.000+00:00',
+          published_at: '2022-01-25T09:35:16.000+00:00',
+          custom_excerpt: null,
+          codeinjection_head: null,
+          codeinjection_foot: null,
+          custom_template: null,
+          canonical_url: null,
+          url: 'http://localhost:2368/hello/',
+          excerpt:
+            '« Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus.\n' +
+            'Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed,\n' +
+            'dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper\n' +
+            'congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est\n' +
+            'eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu\n' +
+            'massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut\n' +
+            'in risus volutpat libero pharetra tem',
+          reading_time: 1,
+          page: true,
+          access: true,
+          og_image: null,
+          og_title: null,
+          og_description: null,
+          twitter_image: null,
+          twitter_title: null,
+          twitter_description: null,
+          meta_title: null,
+          meta_description: null,
+          frontmatter: null,
+        },
+      ];
+      const axiosResult: AxiosResponse = {
+        data: {
+          pages: data,
+        },
+        status: 200,
+        statusText: 'OK',
+        headers: {},
+        config: {},
+      };
+      httpServiceMock.get.mockImplementationOnce(() => of(axiosResult));
+      const result = await (await controller.getPagebySlug('hello')).toPromise();
+      expect(result.pages).toStrictEqual(data);
+    });
+  });
+});
diff --git a/src/pages/pages.controller.ts b/src/pages/pages.controller.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4da25e34a96a5e3cf330098c5f5f33d436208864
--- /dev/null
+++ b/src/pages/pages.controller.ts
@@ -0,0 +1,31 @@
+import { Controller, Get, HttpService, HttpException, HttpStatus, Logger, Param } from '@nestjs/common';
+import { ConfigurationService } from '../configuration/configuration.service';
+import { Observable } from 'rxjs';
+import { catchError, map } from 'rxjs/operators';
+import { Page } from './schemas/page.schema';
+import { rewriteGhostImgUrl } from '../shared/utils';
+
+@Controller('pages')
+export class PagesController {
+  private readonly logger = new Logger(PagesController.name);
+  constructor(private readonly httpService: HttpService, private readonly configService: ConfigurationService) {}
+
+  @Get(':slug')
+  public async getPagebySlug(@Param('slug') slug: string): Promise<Observable<{ pages: Page[] }>> {
+    return this.httpService
+      .get(`${process.env.GHOST_HOST_AND_PORT}/ghost/api/v3/content/pages/slug/` + slug, {
+        params: {
+          key: process.env.GHOST_CONTENT_API_KEY,
+        },
+      })
+      .pipe(
+        map((response) => {
+          return { pages: [rewriteGhostImgUrl(this.configService, response.data.pages[0])] };
+        }),
+        catchError((err) => {
+          this.logger.error(err);
+          throw new HttpException('Page not found:' + err, HttpStatus.NOT_FOUND);
+        })
+      );
+  }
+}
diff --git a/src/pages/pages.module.ts b/src/pages/pages.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c23ce7138213ae0fa5df86d3b2c73cffd93175cd
--- /dev/null
+++ b/src/pages/pages.module.ts
@@ -0,0 +1,8 @@
+import { HttpModule, Module } from '@nestjs/common';
+import { PagesController } from './pages.controller';
+
+@Module({
+  imports: [HttpModule],
+  controllers: [PagesController],
+})
+export class PagesModule {}
diff --git a/src/pages/schemas/page.schema.ts b/src/pages/schemas/page.schema.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cdcdac58c241706189fc29b7842ca110d320dbac
--- /dev/null
+++ b/src/pages/schemas/page.schema.ts
@@ -0,0 +1,39 @@
+export class Page {
+  id: string;
+  uuid: string;
+  title: string;
+  slug: string;
+  html: string;
+  comment_id: string;
+  feature_image: string;
+  featured: false;
+  visibility: string;
+  email_recipient_filter: string;
+  created_at: string;
+  updated_at: string;
+  published_at: string;
+  url: string;
+  excerpt: string;
+  custom_excerpt: string;
+  reading_time: string;
+  access: boolean;
+  send_email_when_published: boolean;
+  og_image: string;
+  og_title: string;
+  og_description: string;
+  twitter_image: string;
+  twitter_title: string;
+  twitter_description: string;
+  meta_title: string;
+  meta_description: string;
+  email_subject: string;
+  codeinjection_head: string;
+  codeinjection_foot: string;
+  custom_template: string;
+  canonical_url: string;
+  tags: [];
+  authors: [];
+  primary_author: [];
+  primary_tag: [];
+  frontmatter: [];
+}
diff --git a/src/posts/posts.service.ts b/src/posts/posts.service.ts
index b1dd31ce24db8bd3b0bcb6eacf0d00539d9e4d67..f76155787a74299c5f1cbe16b7bd1dbf8bccf645 100644
--- a/src/posts/posts.service.ts
+++ b/src/posts/posts.service.ts
@@ -5,6 +5,7 @@ import { ConfigurationService } from '../configuration/configuration.service';
 import { TagEnum } from './enums/tag.enum';
 import { Post } from './schemas/post.schema';
 import { Tag } from './schemas/tag.schema';
+import { rewriteGhostImgUrl } from '../shared/utils';
 
 @Injectable()
 export class PostsService {
@@ -74,15 +75,7 @@ export class PostsService {
     }
 
     // Handle image display. Rewrite image URL to fit ghost infra issue.
-    if (!this.configService.isLocalConf()) {
-      if (postData.feature_image) {
-        postData.feature_image = `https://${this.configService.config.host}/blog/content${
-          postData.feature_image.split('/content')[1]
-        }`;
-      }
-      const regex = /(https?:\/\/ghost):(\d*)?/g;
-      postData.html = postData.html.replace(regex, `https://${this.configService.config.host}/blog`);
-    }
+    postData = rewriteGhostImgUrl(this.configService, postData);
     return postData;
   }
 }
diff --git a/src/shared/utils.ts b/src/shared/utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..58791720252aaf47ea4b4206f3057320d5d894b4
--- /dev/null
+++ b/src/shared/utils.ts
@@ -0,0 +1,17 @@
+import { ConfigurationService } from '../configuration/configuration.service';
+import { Page } from '../pages/schemas/page.schema';
+import { Post } from '../posts/schemas/post.schema';
+
+export function rewriteGhostImgUrl(configService: ConfigurationService, itemData: Page | Post): Page | Post {
+  // Handle image display. Rewrite image URL to fit ghost infra issue.
+  if (!configService.isLocalConf()) {
+    if (itemData.feature_image) {
+      itemData.feature_image = `https://${configService.config.host}/blog/content${
+        itemData.feature_image.split('/content')[1]
+      }`;
+    }
+    const regex = /(https?:\/\/ghost):(\d*)?/g;
+    itemData.html = itemData.html.replace(regex, `https://${configService.config.host}/blog`);
+  }
+  return itemData;
+}
diff --git a/src/structures/interfaces/structure-search-response.interface.ts b/src/structures/interfaces/structure-search-response.interface.ts
index 79c5e31df2bfc3265023440dd17fc69c7ffae8c6..8faccec6fc3956131e90eabdfc296eaa4e9b8f98 100644
--- a/src/structures/interfaces/structure-search-response.interface.ts
+++ b/src/structures/interfaces/structure-search-response.interface.ts
@@ -3,6 +3,7 @@ import { StructureSearchBody } from './structure-search-body.interface';
 export interface StructureSearchResult {
   hits: {
     total: number;
+    max_score: number;
     hits: Array<{
       _score: number;
       _source: StructureSearchBody;
diff --git a/src/structures/services/structure.service.spec.ts b/src/structures/services/structure.service.spec.ts
index 82128e4105f934f8062832a0b90b5cc21b25ab4e..87160583d02726edf20689229bbbad5c37ed9232 100644
--- a/src/structures/services/structure.service.spec.ts
+++ b/src/structures/services/structure.service.spec.ts
@@ -44,6 +44,7 @@ describe('StructuresService', () => {
     }).compile();
 
     service = module.get<StructuresService>(StructuresService);
+    service['structuresSearchService']['index'] = 'structures-unit-test';
   });
 
   it('should be defined', () => {
diff --git a/src/structures/services/structures-search.service.spec.ts b/src/structures/services/structures-search.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ed226632d31a01e424d865f37166a39a6a61679d
--- /dev/null
+++ b/src/structures/services/structures-search.service.spec.ts
@@ -0,0 +1,77 @@
+import { Logger } from '@nestjs/common';
+import { ConfigModule } from '@nestjs/config';
+import { Test, TestingModule } from '@nestjs/testing';
+import { StructuresForSearchServiceMock } from '../../../test/mock/services/structures-for-search.mock.service';
+import { MailerModule } from '../../mailer/mailer.module';
+import { SearchModule } from '../../search/search.module';
+import { StructuresSearchService } from './structures-search.service';
+import { StructuresService } from './structures.service';
+describe('StructuresSearchService', () => {
+  let service: StructuresSearchService;
+
+  beforeEach(async () => {
+    const module: TestingModule = await Test.createTestingModule({
+      imports: [MailerModule, SearchModule, ConfigModule],
+      providers: [
+        StructuresSearchService,
+        {
+          provide: StructuresService,
+          useClass: StructuresForSearchServiceMock,
+        },
+      ],
+    }).compile();
+
+    service = module.get<StructuresSearchService>(StructuresSearchService);
+    service['index'] = 'structures-unit-test';
+  });
+
+  it('should be defined', () => {
+    expect(service).toBeDefined();
+  });
+
+  it('should create index', async () => {
+    await service.dropIndex();
+    const res = await service.createStructureIndex();
+    expect(res).toBeTruthy();
+  });
+
+  it('should index structures', async () => {
+    const structuresForSearchService = new StructuresForSearchServiceMock();
+    const structures = structuresForSearchService.findAll();
+
+    const res = await Promise.all(
+      structures.map((structure: any) => {
+        service.indexStructure(structure);
+      })
+    );
+    expect(res).toBeTruthy();
+
+    // wait for the new structures to be indexed before search
+    await service.refreshIndexStructure();
+    // but we still need to wait the refresh to be done
+    await new Promise((r) => setTimeout(r, 1000));
+  });
+
+  it('should find maisons de la métropole', async () => {
+    const res = await service.search('maison de la');
+    //Logger.log(JSON.stringify(res));
+    expect(res[0].structureName).toContain('Maison de la Métropole');
+    expect(res[1].structureName).toContain('Maison de la Métropole');
+  });
+
+  it('should find metropole', async () => {
+    const res = await service.search('metropole');
+    expect(res[0].structureName).toContain('Métropole');
+  });
+
+  it('should find text in description', async () => {
+    const res = await service.search('liseuse');
+    expect(res.length).toBe(1);
+    expect(res[0].structureName).toContain("Médiathèque d'Ecully");
+  });
+
+  it('should drop index', async () => {
+    const res = await service.dropIndex();
+    expect(res).toBeTruthy();
+  });
+});
diff --git a/src/structures/services/structures-search.service.ts b/src/structures/services/structures-search.service.ts
index bd6f53beef23ba2148b6325e9ac713ecb5e75af1..9e17f5a672e5d5e937f3ad967999974ac492e353 100644
--- a/src/structures/services/structures-search.service.ts
+++ b/src/structures/services/structures-search.service.ts
@@ -29,6 +29,20 @@ export class StructuresSearchService {
   public async createStructureIndex(): Promise<any> {
     return this.elasticsearchService.indices.create({
       index: this.index,
+      body: {
+        settings: {
+          analysis: {
+            analyzer: {
+              default: {
+                type: 'french',
+              },
+              default_search: {
+                type: 'french',
+              },
+            },
+          },
+        },
+      },
     });
   }
 
@@ -54,6 +68,12 @@ export class StructuresSearchService {
     return structure;
   }
 
+  public async refreshIndexStructure(): Promise<any> {
+    return this.elasticsearchService.indices.refresh({
+      index: this.index,
+    });
+  }
+
   public async search(searchString: string): Promise<StructureSearchBody[]> {
     searchString = searchString ? searchString + '*' : '*';
     const { body } = await this.elasticsearchService.search<StructureSearchResult>({
@@ -71,14 +91,8 @@ export class StructuresSearchService {
         },
       },
     });
-    const maxScore = Math.max.apply(
-      Math,
-      body.hits.hits.map(function (hit) {
-        return hit._score;
-      })
-    );
     const sortedHits = body.hits.hits.filter(function (elem) {
-      return elem._score >= maxScore / 1.5;
+      return elem._score >= body.hits.max_score / 1.5;
     });
     return sortedHits.map((item) => item._source);
   }
diff --git a/test/mock/services/structures-for-search.mock.service.ts b/test/mock/services/structures-for-search.mock.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..766f721fd8bb675ea1b141944dd31533aed588e0
--- /dev/null
+++ b/test/mock/services/structures-for-search.mock.service.ts
@@ -0,0 +1,62 @@
+export class StructuresForSearchServiceMock {
+  findAll() {
+    return [
+      {
+        _id: '607ef197225ffd001391edb9',
+        structureName: "Médiathèque d'Ecully",
+        structureType: 'mediatheque',
+        address: {
+          numero: '1',
+          street: 'Avenue Edouard Aynard',
+          commune: 'Écully',
+        },
+        description:
+          'Nous sommes une équipe de 6 personnes accompagnant les usagers dans leur démarche de découverte des outils numériques, mettant à disposition sous forme de prêt des liseuses et du livre numérique et organisant des ateliers individuels de prise en main des outils numériques et tentant de répondre aux questions des usages sur des sujets divers.',
+      },
+      {
+        _id: '60368194cda3ba42b8e621dd',
+        structureName: 'Maison des associations (Grézieu-la-Varenne)',
+        structureType: 'autre',
+        address: {
+          numero: null,
+          street: " Place de l'Abbe Launay",
+          commune: 'Grézieu-la-Varenne',
+        },
+        description: null,
+      },
+      {
+        _id: '60b4b0836a9d4500313b8661',
+        structureName: 'Mairie (La Tour de Salvagny)',
+        structureType: 'mairie',
+        address: {
+          numero: null,
+          street: 'Place de la Mairie',
+          commune: 'La Tour-de-Salvagny',
+        },
+        description: null,
+      },
+      {
+        _id: '604b84e914d486001790ee57',
+        structureName: 'Maison de la Métropole (Ecully)',
+        structureType: 'mdm',
+        address: {
+          numero: '10',
+          street: 'Chemin Jean-Marie Vianney',
+          commune: 'Écully',
+        },
+        description: null,
+      },
+      {
+        _id: '61977124eb90f20031137c35',
+        structureName: 'Maison de la Métropole (Oullins)',
+        structureType: 'mdm',
+        address: {
+          numero: '17',
+          street: 'Rue Tupin',
+          commune: 'Oullins',
+        },
+        description: null,
+      },
+    ];
+  }
+}