diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx
index 030e967bd..a7db0d900 100644
--- a/.storybook/preview.tsx
+++ b/.storybook/preview.tsx
@@ -1,5 +1,6 @@
 import type { Preview } from '@storybook/react'
 import { ThemeProvider } from '@iqss/dataverse-design-system'
+import { MemoryRouter } from 'react-router-dom'
 
 const preview: Preview = {
   parameters: {
@@ -14,7 +15,9 @@ const preview: Preview = {
   decorators: [
     (Story) => (
       <ThemeProvider>
-        <Story />
+        <MemoryRouter>
+          <Story />
+        </MemoryRouter>
       </ThemeProvider>
     )
   ]
diff --git a/merged-coverage/lcov.info b/merged-coverage/lcov.info
index 9c8729e8c..8d7a2182a 100644
--- a/merged-coverage/lcov.info
+++ b/merged-coverage/lcov.info
@@ -7,7 +7,7 @@ DA:5,108
 BRDA:1,0,0,108
 BRDA:1,0,1,108
 end_of_record
-SF:src/sections/hello-dataverse/HelloDataverse.tsx
+SF:src/sections/hello-dataverse/Home.tsx
 DA:5,76
 DA:6,76
 DA:8,38
diff --git a/public/locales/en/files.json b/public/locales/en/files.json
index 98fc2b0bb..bbae885f1 100644
--- a/public/locales/en/files.json
+++ b/public/locales/en/files.json
@@ -8,9 +8,6 @@
       "clearSelection": "Clear selection."
     },
     "zipDownloadExceedsLimit": "The overall size of the files selected ({{selectionTotalSize}}) for download exceeds the zip limit of {{zipDownloadSizeLimit}}. Please unselect some files to continue.",
-    "pagination": {
-      "pageSize": "Files per page"
-    },
     "tabularData": {
       "name": "Tabular Data",
       "variables": "Variables",
diff --git a/public/locales/en/helloDataverse.json b/public/locales/en/helloDataverse.json
deleted file mode 100644
index 8c947e521..000000000
--- a/public/locales/en/helloDataverse.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "title": "Hello Dataverse",
-  "linkText": "Dataverse",
-  "description": "Edit <1>src/sections/hello-dataverse/HelloDataverse.tsx</1> and save to reload.",
-  "altImage": "Dataverse logo"
-}
diff --git a/public/locales/en/home.json b/public/locales/en/home.json
new file mode 100644
index 000000000..2da05e5f9
--- /dev/null
+++ b/public/locales/en/home.json
@@ -0,0 +1,7 @@
+{
+  "title": "Root",
+  "noDatasetsMessage": {
+    "authenticated": "This dataverse currently has no datasets. You can add to it by using the Add Data button on this page.",
+    "anonymous": "This dataverse currently has no datasets. Please <1>log in</1> to see if you are able to add to it."
+  }
+}
diff --git a/public/locales/en/pagination.json b/public/locales/en/pagination.json
new file mode 100644
index 000000000..e30599934
--- /dev/null
+++ b/public/locales/en/pagination.json
@@ -0,0 +1,4 @@
+{
+  "results": "{{start}} to {{end}} of {{total}} {{item}}s",
+  "pageSize": "{{item}}s per page"
+}
diff --git a/src/Router.tsx b/src/Router.tsx
index 38d016834..286a80f63 100644
--- a/src/Router.tsx
+++ b/src/Router.tsx
@@ -1,8 +1,8 @@
 import { createBrowserRouter, RouterProvider } from 'react-router-dom'
-import { HelloDataverse } from './sections/hello-dataverse/HelloDataverse'
 import { Layout } from './sections/layout/Layout'
 import { Route } from './sections/Route.enum'
 import { DatasetFactory } from './sections/dataset/DatasetFactory'
+import { HomeFactory } from './sections/home/HomeFactory'
 
 const router = createBrowserRouter(
   [
@@ -12,7 +12,7 @@ const router = createBrowserRouter(
       children: [
         {
           path: Route.HOME,
-          element: <HelloDataverse />
+          element: HomeFactory.create()
         },
         {
           path: `${Route.DATASETS}`,
diff --git a/src/dataset/domain/models/Dataset.ts b/src/dataset/domain/models/Dataset.ts
index caaaae045..657fb4eac 100644
--- a/src/dataset/domain/models/Dataset.ts
+++ b/src/dataset/domain/models/Dataset.ts
@@ -291,7 +291,7 @@ export class Dataset {
     public readonly privateUrl?: PrivateUrl
   ) {}
 
-  public getTitle(): string {
+  public get title(): string {
     return this.metadataBlocks[0].fields.title
   }
 
diff --git a/src/dataset/domain/models/DatasetPaginationInfo.ts b/src/dataset/domain/models/DatasetPaginationInfo.ts
new file mode 100644
index 000000000..e9d88e6f4
--- /dev/null
+++ b/src/dataset/domain/models/DatasetPaginationInfo.ts
@@ -0,0 +1,7 @@
+import { PaginationInfo } from '../../../shared/domain/models/PaginationInfo'
+
+export class DatasetPaginationInfo extends PaginationInfo<DatasetPaginationInfo> {
+  constructor(page = 1, pageSize = 10, totalItems = 0, itemName = 'Dataset') {
+    super(page, pageSize, totalItems, itemName)
+  }
+}
diff --git a/src/dataset/domain/models/DatasetPreview.ts b/src/dataset/domain/models/DatasetPreview.ts
new file mode 100644
index 000000000..849ba4691
--- /dev/null
+++ b/src/dataset/domain/models/DatasetPreview.ts
@@ -0,0 +1,22 @@
+import { DatasetLabel, DatasetVersion } from './Dataset'
+
+export class DatasetPreview {
+  constructor(
+    public persistentId: string,
+    public title: string,
+    public version: DatasetVersion,
+    public citation: string,
+    public labels: DatasetLabel[],
+    public isDeaccessioned: boolean,
+    public releaseOrCreateDate: Date,
+    public description: string,
+    public thumbnail?: string
+  ) {}
+
+  get abbreviatedDescription(): string {
+    if (this.description.length > 280) {
+      return `${this.description.substring(0, 280)}...`
+    }
+    return this.description
+  }
+}
diff --git a/src/dataset/domain/models/TotalDatasetsCount.ts b/src/dataset/domain/models/TotalDatasetsCount.ts
new file mode 100644
index 000000000..acc302966
--- /dev/null
+++ b/src/dataset/domain/models/TotalDatasetsCount.ts
@@ -0,0 +1 @@
+export type TotalDatasetsCount = number
diff --git a/src/dataset/domain/repositories/DatasetRepository.ts b/src/dataset/domain/repositories/DatasetRepository.ts
index a836e867b..0cc96a13d 100644
--- a/src/dataset/domain/repositories/DatasetRepository.ts
+++ b/src/dataset/domain/repositories/DatasetRepository.ts
@@ -1,6 +1,11 @@
 import { Dataset } from '../models/Dataset'
+import { TotalDatasetsCount } from '../models/TotalDatasetsCount'
+import { DatasetPaginationInfo } from '../models/DatasetPaginationInfo'
+import { DatasetPreview } from '../models/DatasetPreview'
 
 export interface DatasetRepository {
   getByPersistentId: (persistentId: string, version?: string) => Promise<Dataset | undefined>
   getByPrivateUrlToken: (privateUrlToken: string) => Promise<Dataset | undefined>
+  getAll: (paginationInfo: DatasetPaginationInfo) => Promise<DatasetPreview[]>
+  getTotalDatasetsCount: () => Promise<TotalDatasetsCount>
 }
diff --git a/src/dataset/domain/useCases/getDatasets.ts b/src/dataset/domain/useCases/getDatasets.ts
new file mode 100644
index 000000000..e10f74a2c
--- /dev/null
+++ b/src/dataset/domain/useCases/getDatasets.ts
@@ -0,0 +1,12 @@
+import { DatasetRepository } from '../repositories/DatasetRepository'
+import { DatasetPaginationInfo } from '../models/DatasetPaginationInfo'
+import { DatasetPreview } from '../models/DatasetPreview'
+
+export async function getDatasets(
+  datasetRepository: DatasetRepository,
+  paginationInfo: DatasetPaginationInfo
+): Promise<DatasetPreview[]> {
+  return datasetRepository.getAll(paginationInfo).catch((error: Error) => {
+    throw new Error(error.message)
+  })
+}
diff --git a/src/dataset/domain/useCases/getTotalDatasetsCount.ts b/src/dataset/domain/useCases/getTotalDatasetsCount.ts
new file mode 100644
index 000000000..5ba855d06
--- /dev/null
+++ b/src/dataset/domain/useCases/getTotalDatasetsCount.ts
@@ -0,0 +1,10 @@
+import { DatasetRepository } from '../repositories/DatasetRepository'
+import { TotalDatasetsCount } from '../models/TotalDatasetsCount'
+
+export async function getTotalDatasetsCount(
+  datasetRepository: DatasetRepository
+): Promise<TotalDatasetsCount> {
+  return datasetRepository.getTotalDatasetsCount().catch((error: Error) => {
+    throw new Error(error.message)
+  })
+}
diff --git a/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts b/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts
index c3773641b..b5ddf718c 100644
--- a/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts
+++ b/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts
@@ -16,9 +16,32 @@ import {
   FileDownloadSizeMode
 } from '@iqss/dataverse-client-javascript'
 import { JSDatasetMapper } from '../mappers/JSDatasetMapper'
+import { TotalDatasetsCount } from '../../domain/models/TotalDatasetsCount'
+import { DatasetPaginationInfo } from '../../domain/models/DatasetPaginationInfo'
+import { DatasetPreview } from '../../domain/models/DatasetPreview'
+import { DatasetPreviewMother } from '../../../../tests/component/dataset/domain/models/DatasetPreviewMother'
 
 const includeDeaccessioned = true
 export class DatasetJSDataverseRepository implements DatasetRepository {
+  // eslint-disable-next-line unused-imports/no-unused-vars
+  getAll(paginationInfo: DatasetPaginationInfo): Promise<DatasetPreview[]> {
+    // TODO - Implement using the js-dataverse-client
+    return new Promise((resolve) => {
+      setTimeout(() => {
+        resolve(DatasetPreviewMother.createManyRealistic(10))
+      }, 1000)
+    })
+  }
+
+  getTotalDatasetsCount(): Promise<TotalDatasetsCount> {
+    // TODO - Implement using the js-dataverse-client
+    return new Promise((resolve) => {
+      setTimeout(() => {
+        resolve(200)
+      }, 1000)
+    })
+  }
+
   getByPersistentId(
     persistentId: string,
     version?: string,
diff --git a/src/files/domain/models/FilePaginationInfo.ts b/src/files/domain/models/FilePaginationInfo.ts
index fbef8d177..f2b4386af 100644
--- a/src/files/domain/models/FilePaginationInfo.ts
+++ b/src/files/domain/models/FilePaginationInfo.ts
@@ -1,52 +1,7 @@
-export class FilePaginationInfo {
-  constructor(
-    public readonly page: number = 1,
-    public readonly pageSize: number = 10,
-    public readonly totalFiles: number = 0
-  ) {}
+import { PaginationInfo } from '../../../shared/domain/models/PaginationInfo'
 
-  withTotal(total: number): FilePaginationInfo {
-    return new FilePaginationInfo(this.page, this.pageSize, total)
-  }
-  goToPage(page: number): FilePaginationInfo {
-    return new FilePaginationInfo(page, this.pageSize, this.totalFiles)
-  }
-
-  goToPreviousPage(): FilePaginationInfo {
-    if (!this.previousPage) throw new Error('No previous page')
-    return this.goToPage(this.previousPage)
-  }
-
-  goToNextPage(): FilePaginationInfo {
-    if (!this.nextPage) throw new Error('No next page')
-    return this.goToPage(this.nextPage)
-  }
-
-  withPageSize(pageSize: number): FilePaginationInfo {
-    const getNewPage = (oldPageSize: number, newPageSize: number) => {
-      const newPage = Math.ceil(((this.page - 1) * oldPageSize + 1) / newPageSize)
-      return newPage > 0 ? newPage : 1
-    }
-    return new FilePaginationInfo(getNewPage(this.pageSize, pageSize), pageSize, this.totalFiles)
-  }
-
-  get totalPages(): number {
-    return Math.ceil(this.totalFiles / this.pageSize)
-  }
-
-  get hasPreviousPage(): boolean {
-    return this.page > 1
-  }
-
-  get hasNextPage(): boolean {
-    return this.page < this.totalPages
-  }
-
-  get previousPage(): number | undefined {
-    return this.hasPreviousPage ? this.page - 1 : undefined
-  }
-
-  get nextPage(): number | undefined {
-    return this.hasNextPage ? this.page + 1 : undefined
+export class FilePaginationInfo extends PaginationInfo<FilePaginationInfo> {
+  constructor(page = 1, pageSize = 10, totalItems = 0, itemName = 'File') {
+    super(page, pageSize, totalItems, itemName)
   }
 }
diff --git a/src/files/domain/repositories/FileRepository.ts b/src/files/domain/repositories/FileRepository.ts
index 9b861084d..278fc9502 100644
--- a/src/files/domain/repositories/FileRepository.ts
+++ b/src/files/domain/repositories/FileRepository.ts
@@ -1,9 +1,9 @@
 import { File, FileDownloadMode } from '../models/File'
 import { FileCriteria } from '../models/FileCriteria'
 import { FilesCountInfo } from '../models/FilesCountInfo'
-import { FilePaginationInfo } from '../models/FilePaginationInfo'
 import { FileUserPermissions } from '../models/FileUserPermissions'
 import { DatasetVersion } from '../../../dataset/domain/models/Dataset'
+import { FilePaginationInfo } from '../models/FilePaginationInfo'
 
 export interface FileRepository {
   getAllByDatasetPersistentId: (
diff --git a/src/files/domain/useCases/getFilesByDatasetPersistentId.ts b/src/files/domain/useCases/getFilesByDatasetPersistentId.ts
index 326633b7d..9370c7ebe 100644
--- a/src/files/domain/useCases/getFilesByDatasetPersistentId.ts
+++ b/src/files/domain/useCases/getFilesByDatasetPersistentId.ts
@@ -1,8 +1,8 @@
 import { FileRepository } from '../repositories/FileRepository'
 import { File } from '../models/File'
 import { FileCriteria } from '../models/FileCriteria'
-import { FilePaginationInfo } from '../models/FilePaginationInfo'
 import { DatasetVersion } from '../../../dataset/domain/models/Dataset'
+import { FilePaginationInfo } from '../models/FilePaginationInfo'
 
 export async function getFilesByDatasetPersistentId(
   fileRepository: FileRepository,
diff --git a/src/files/infrastructure/FileJSDataverseRepository.ts b/src/files/infrastructure/FileJSDataverseRepository.ts
index 96affa553..64b46ce53 100644
--- a/src/files/infrastructure/FileJSDataverseRepository.ts
+++ b/src/files/infrastructure/FileJSDataverseRepository.ts
@@ -1,7 +1,6 @@
 import { FileRepository } from '../domain/repositories/FileRepository'
 import { File, FileDownloadMode } from '../domain/models/File'
 import { FilesCountInfo } from '../domain/models/FilesCountInfo'
-import { FilePaginationInfo } from '../domain/models/FilePaginationInfo'
 import { FileUserPermissions } from '../domain/models/FileUserPermissions'
 import {
   File as JSFile,
@@ -19,6 +18,7 @@ import { FileCriteria } from '../domain/models/FileCriteria'
 import { DomainFileMapper } from './mappers/DomainFileMapper'
 import { JSFileMapper } from './mappers/JSFileMapper'
 import { DatasetVersion } from '../../dataset/domain/models/Dataset'
+import { FilePaginationInfo } from '../domain/models/FilePaginationInfo'
 
 const includeDeaccessioned = true
 
diff --git a/src/files/infrastructure/mappers/DomainFileMapper.ts b/src/files/infrastructure/mappers/DomainFileMapper.ts
index 71082838d..9c8921102 100644
--- a/src/files/infrastructure/mappers/DomainFileMapper.ts
+++ b/src/files/infrastructure/mappers/DomainFileMapper.ts
@@ -1,4 +1,3 @@
-import { FilePaginationInfo } from '../../domain/models/FilePaginationInfo'
 import {
   FileAccessOption,
   FileCriteria,
@@ -11,6 +10,7 @@ import {
   FileOrderCriteria as JSFileOrderCriteria
 } from '@iqss/dataverse-client-javascript'
 import { FileType } from '../../domain/models/File'
+import { FilePaginationInfo } from '../../domain/models/FilePaginationInfo'
 
 export class DomainFileMapper {
   static toJSPagination(paginationInfo: FilePaginationInfo): {
diff --git a/src/sections/dataset/Dataset.tsx b/src/sections/dataset/Dataset.tsx
index 8095e0ae8..86e6b69f1 100644
--- a/src/sections/dataset/Dataset.tsx
+++ b/src/sections/dataset/Dataset.tsx
@@ -51,14 +51,14 @@ export function Dataset({ fileRepository }: DatasetProps) {
           </div>
 
           <header className={styles.header}>
-            <h1>{dataset.getTitle()}</h1>
+            <h1>{dataset.title}</h1>
             <DatasetLabels labels={dataset.labels} />
           </header>
           <div className={styles.container}>
             <Row>
               <Col sm={9}>
                 <DatasetCitation
-                  title={dataset.getTitle()}
+                  title={dataset.title}
                   thumbnail={dataset.thumbnail}
                   citation={dataset.citation}
                   version={dataset.version}
diff --git a/src/sections/dataset/dataset-citation/CitationThumbnail.tsx b/src/sections/dataset/dataset-citation/CitationThumbnail.tsx
deleted file mode 100644
index 57cda7c95..000000000
--- a/src/sections/dataset/dataset-citation/CitationThumbnail.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { DatasetPublishingStatus } from '../../../dataset/domain/models/Dataset'
-import styles from './DatasetCitation.module.scss'
-import { Icon, IconName } from '@iqss/dataverse-design-system'
-
-interface CitationThumbnailProps {
-  thumbnail?: string
-  title: string
-  publishingStatus: DatasetPublishingStatus
-}
-
-export function CitationThumbnail({ thumbnail, title, publishingStatus }: CitationThumbnailProps) {
-  if (thumbnail && publishingStatus !== DatasetPublishingStatus.DEACCESSIONED) {
-    return <img className={styles['preview-image']} src={thumbnail} alt={title} />
-  }
-
-  return (
-    <div className={styles.icon}>
-      <Icon name={IconName.DATASET} />
-    </div>
-  )
-}
diff --git a/src/sections/dataset/dataset-citation/DatasetCitation.module.scss b/src/sections/dataset/dataset-citation/DatasetCitation.module.scss
index 4e3ecc9ea..4dfa0ae50 100644
--- a/src/sections/dataset/dataset-citation/DatasetCitation.module.scss
+++ b/src/sections/dataset/dataset-citation/DatasetCitation.module.scss
@@ -17,20 +17,11 @@ min-height: 150px;
     border: 1px solid $dv-danger-color;
 }
 
-.icon {
-    color: #428BCA;
-    font-size: 7.5em;
-    line-height: 1.1;
-}
-
-.preview-image {
-    width: 100%;
-    max-width: 140px;
-    height: auto;
-    max-height: 140px;
-}
-
 .row {
     margin-right: -15px;
     margin-left: -15px;
+}
+
+.thumbnail {
+    font-size: 7.5em;
 }
\ No newline at end of file
diff --git a/src/sections/dataset/dataset-citation/DatasetCitation.tsx b/src/sections/dataset/dataset-citation/DatasetCitation.tsx
index 9b523c7c7..9f1450830 100644
--- a/src/sections/dataset/dataset-citation/DatasetCitation.tsx
+++ b/src/sections/dataset/dataset-citation/DatasetCitation.tsx
@@ -1,9 +1,10 @@
-import { Col, QuestionMarkTooltip, Row } from '@iqss/dataverse-design-system'
+import { Col, Row } from '@iqss/dataverse-design-system'
 import styles from './DatasetCitation.module.scss'
 import { useTranslation } from 'react-i18next'
 import { DatasetPublishingStatus, DatasetVersion } from '../../../dataset/domain/models/Dataset'
-import parse from 'html-react-parser'
-import { CitationThumbnail } from './CitationThumbnail'
+import { DatasetThumbnail } from '../dataset-thumbnail/DatasetThumbnail'
+import { CitationDescription } from '../../shared/citation/CitationDescription'
+import { DatasetCitationTooltip } from './DatasetCitationTooltip'
 
 interface DatasetCitationProps {
   thumbnail?: string
@@ -23,16 +24,19 @@ export function DatasetCitation({ thumbnail, title, citation, version }: Dataset
             : styles.container
         }>
         <Row className={styles.row}>
-          <Col sm={2}>
-            <CitationThumbnail
+          <Col sm={2} className={styles.thumbnail}>
+            <DatasetThumbnail
               thumbnail={thumbnail}
               title={title}
-              publishingStatus={version.publishingStatus}
+              isDeaccessioned={version.publishingStatus === DatasetPublishingStatus.DEACCESSIONED}
             />
           </Col>
           <Col>
             <Row>
-              <CitationDescription citation={citation} version={version} />
+              <span className={styles.citation}>
+                <CitationDescription citation={citation} />
+                <DatasetCitationTooltip status={version.publishingStatus} />
+              </span>
             </Row>
             <Row>
               <div>
@@ -52,35 +56,3 @@ export function DatasetCitation({ thumbnail, title, citation, version }: Dataset
     </>
   )
 }
-
-function CitationDescription({ citation, version }: { citation: string; version: DatasetVersion }) {
-  const citationAsReactElement = parse(citation)
-
-  return (
-    <span className={styles.citation}>
-      {citationAsReactElement}
-      <CitationTooltip status={version.publishingStatus} />
-    </span>
-  )
-}
-
-interface CitationDatasetStatusProps {
-  status: DatasetPublishingStatus
-}
-
-function CitationTooltip({ status }: CitationDatasetStatusProps) {
-  const { t } = useTranslation('dataset')
-
-  if (status !== DatasetPublishingStatus.RELEASED) {
-    return (
-      <>
-        {' '}
-        <QuestionMarkTooltip
-          placement={'top'}
-          message={t(`citation.status.${status}.description`)}
-        />
-      </>
-    )
-  }
-  return <></>
-}
diff --git a/src/sections/dataset/dataset-citation/DatasetCitationTooltip.tsx b/src/sections/dataset/dataset-citation/DatasetCitationTooltip.tsx
new file mode 100644
index 000000000..0ae1676b1
--- /dev/null
+++ b/src/sections/dataset/dataset-citation/DatasetCitationTooltip.tsx
@@ -0,0 +1,24 @@
+import { DatasetPublishingStatus } from '../../../dataset/domain/models/Dataset'
+import { useTranslation } from 'react-i18next'
+import { QuestionMarkTooltip } from '@iqss/dataverse-design-system'
+
+interface DatasetCitationTooltipProps {
+  status: DatasetPublishingStatus
+}
+
+export function DatasetCitationTooltip({ status }: DatasetCitationTooltipProps) {
+  const { t } = useTranslation('dataset')
+
+  if (status !== DatasetPublishingStatus.RELEASED) {
+    return (
+      <>
+        {' '}
+        <QuestionMarkTooltip
+          placement={'top'}
+          message={t(`citation.status.${status}.description`)}
+        />
+      </>
+    )
+  }
+  return <></>
+}
diff --git a/src/sections/dataset/dataset-files/DatasetFiles.tsx b/src/sections/dataset/dataset-files/DatasetFiles.tsx
index cccd061a5..afb96ec8b 100644
--- a/src/sections/dataset/dataset-files/DatasetFiles.tsx
+++ b/src/sections/dataset/dataset-files/DatasetFiles.tsx
@@ -4,9 +4,9 @@ import { FilesTable } from './files-table/FilesTable'
 import { FileCriteriaForm } from './file-criteria-form/FileCriteriaForm'
 import { FileCriteria } from '../../../files/domain/models/FileCriteria'
 import { useFiles } from './useFiles'
-import { FilePaginationInfo } from '../../../files/domain/models/FilePaginationInfo'
-import { FilesPagination } from './files-pagination/FilesPagination'
+import { PaginationControls } from '../../shared/pagination/PaginationControls'
 import { DatasetVersion } from '../../../dataset/domain/models/Dataset'
+import { FilePaginationInfo } from '../../../files/domain/models/FilePaginationInfo'
 
 interface DatasetFilesProps {
   filesRepository: FileRepository
@@ -44,10 +44,8 @@ export function DatasetFiles({
         filesTotalDownloadSize={filesTotalDownloadSize}
         criteria={criteria}
       />
-      <FilesPagination
-        page={paginationInfo.page}
-        pageSize={paginationInfo.pageSize}
-        total={paginationInfo.totalFiles}
+      <PaginationControls
+        initialPaginationInfo={paginationInfo}
         onPaginationInfoChange={setPaginationInfo}
       />
     </>
diff --git a/src/sections/dataset/dataset-files/files-table/FilesTable.tsx b/src/sections/dataset/dataset-files/files-table/FilesTable.tsx
index fc71ef801..b1988bba8 100644
--- a/src/sections/dataset/dataset-files/files-table/FilesTable.tsx
+++ b/src/sections/dataset/dataset-files/files-table/FilesTable.tsx
@@ -6,10 +6,10 @@ import { File } from '../../../../files/domain/models/File'
 import { RowSelectionMessage } from './row-selection/RowSelectionMessage'
 import { ZipDownloadLimitMessage } from './zip-download-limit-message/ZipDownloadLimitMessage'
 import { SpinnerSymbol } from './spinner-symbol/SpinnerSymbol'
-import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo'
 import { useEffect, useState } from 'react'
 import { FileSelection } from './row-selection/useFileSelection'
 import { FileCriteria } from '../../../../files/domain/models/FileCriteria'
+import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo'
 
 interface FilesTableProps {
   files: File[]
@@ -56,7 +56,7 @@ export function FilesTable({
       <RowSelectionMessage
         fileSelection={fileSelection}
         selectAllRows={selectAllFiles}
-        totalFilesCount={paginationInfo.totalFiles}
+        totalFilesCount={paginationInfo.totalItems}
         clearRowSelection={clearFileSelection}
       />
       <ZipDownloadLimitMessage
diff --git a/src/sections/dataset/dataset-files/files-table/FilesTableColumnsDefinition.tsx b/src/sections/dataset/dataset-files/files-table/FilesTableColumnsDefinition.tsx
index bdf534f62..6c241eac0 100644
--- a/src/sections/dataset/dataset-files/files-table/FilesTableColumnsDefinition.tsx
+++ b/src/sections/dataset/dataset-files/files-table/FilesTableColumnsDefinition.tsx
@@ -5,8 +5,8 @@ import { FileInfoCell } from './file-info/file-info-cell/FileInfoCell'
 import { FileInfoHeader } from './file-info/FileInfoHeader'
 import { FileActionsHeader } from './file-actions/FileActionsHeader'
 import { FileActionsCell } from './file-actions/file-actions-cell/FileActionsCell'
-import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo'
 import { FileSelection } from './row-selection/useFileSelection'
+import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo'
 
 export const createColumnsDefinition = (
   paginationInfo: FilePaginationInfo,
diff --git a/src/sections/dataset/dataset-files/files-table/file-info/FileInfoHeader.tsx b/src/sections/dataset/dataset-files/files-table/file-info/FileInfoHeader.tsx
index fd76cc997..b105aa5a4 100644
--- a/src/sections/dataset/dataset-files/files-table/file-info/FileInfoHeader.tsx
+++ b/src/sections/dataset/dataset-files/files-table/file-info/FileInfoHeader.tsx
@@ -1,4 +1,5 @@
 import styles from '../FilesTable.module.scss'
+import { PaginationResultsInfo } from '../../../../shared/pagination/PaginationResultsInfo'
 import { FilePaginationInfo } from '../../../../../files/domain/models/FilePaginationInfo'
 
 interface FileInfoHeaderProps {
@@ -6,16 +7,14 @@ interface FileInfoHeaderProps {
 }
 
 export function FileInfoHeader({ paginationInfo }: FileInfoHeaderProps) {
-  const fileCount = paginationInfo.totalFiles
-  const startIndex = (paginationInfo.page - 1) * paginationInfo.pageSize + 1
-  const endIndex = Math.min(startIndex + paginationInfo.pageSize - 1, fileCount)
+  const fileCount = paginationInfo.totalItems
 
   if (fileCount === 0) {
     return <></>
   }
   return (
     <span className={styles['file-info-header']}>
-      {`${startIndex} to ${endIndex} of ${fileCount} Files`}
+      <PaginationResultsInfo paginationInfo={paginationInfo} />
     </span>
   )
 }
diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate.tsx
index 61ddb0c44..054ab4b89 100644
--- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate.tsx
+++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate.tsx
@@ -1,17 +1,13 @@
 import { FileDate as FileDateModel } from '../../../../../../../files/domain/models/File'
 import { useTranslation } from 'react-i18next'
+import { DateHelper } from '../../../../../../../shared/domain/helpers/DateHelper'
 
 export function FileDate({ date }: { date: FileDateModel }) {
   const { t } = useTranslation('files')
   return (
     <div>
       <span>
-        {t(`table.date.${date.type}`)}{' '}
-        {date.date.toLocaleDateString(Intl.DateTimeFormat().resolvedOptions().locale, {
-          year: 'numeric',
-          month: 'short',
-          day: 'numeric'
-        })}
+        {t(`table.date.${date.type}`)} {DateHelper.toDisplayFormat(date.date)}
       </span>
     </div>
   )
diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileEmbargoDate.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileEmbargoDate.tsx
index 4c61171b9..50db565fa 100644
--- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileEmbargoDate.tsx
+++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileEmbargoDate.tsx
@@ -1,5 +1,6 @@
 import { FileEmbargo, FilePublishingStatus } from '../../../../../../../files/domain/models/File'
 import { useTranslation } from 'react-i18next'
+import { DateHelper } from '../../../../../../../shared/domain/helpers/DateHelper'
 
 interface FileEmbargoDateProps {
   embargo: FileEmbargo | undefined
@@ -17,11 +18,7 @@ export function FileEmbargoDate({ embargo, publishingStatus }: FileEmbargoDatePr
     <div>
       <span>
         {t(embargoTypeOfDate(embargo.isActive, publishingStatus))}{' '}
-        {embargo.dateAvailable.toLocaleDateString(Intl.DateTimeFormat().resolvedOptions().locale, {
-          year: 'numeric',
-          month: 'short',
-          day: 'numeric'
-        })}
+        {DateHelper.toDisplayFormat(embargo.dateAvailable)}
       </span>
     </div>
   )
diff --git a/src/sections/dataset/dataset-files/files-table/row-selection/useFileSelection.ts b/src/sections/dataset/dataset-files/files-table/row-selection/useFileSelection.ts
index ede451ad0..6fe2a12eb 100644
--- a/src/sections/dataset/dataset-files/files-table/row-selection/useFileSelection.ts
+++ b/src/sections/dataset/dataset-files/files-table/row-selection/useFileSelection.ts
@@ -1,8 +1,8 @@
 import { useEffect, useState } from 'react'
-import { FilePaginationInfo } from '../../../../../files/domain/models/FilePaginationInfo'
 import { File } from '../../../../../files/domain/models/File'
 import { Row } from '@tanstack/react-table'
 import { RowSelection } from '../useFilesTable'
+import { FilePaginationInfo } from '../../../../../files/domain/models/FilePaginationInfo'
 
 export type FileSelection = {
   [key: string]: File | undefined
@@ -61,7 +61,7 @@ export function useFileSelection(
   const selectAllFiles = () => {
     setCurrentPageRowSelection(createRowSelection(paginationInfo.pageSize))
 
-    const totalFilesFileSelection = createFileSelection(paginationInfo.totalFiles)
+    const totalFilesFileSelection = createFileSelection(paginationInfo.totalItems)
     const newFileSelection = { ...totalFilesFileSelection, ...fileSelection }
     setFileSelection(newFileSelection)
   }
diff --git a/src/sections/dataset/dataset-files/files-table/useFilesTable.tsx b/src/sections/dataset/dataset-files/files-table/useFilesTable.tsx
index b403e9782..0d4f35fd1 100644
--- a/src/sections/dataset/dataset-files/files-table/useFilesTable.tsx
+++ b/src/sections/dataset/dataset-files/files-table/useFilesTable.tsx
@@ -2,8 +2,8 @@ import { useEffect, useState } from 'react'
 import { File } from '../../../../files/domain/models/File'
 import { getCoreRowModel, Row, useReactTable } from '@tanstack/react-table'
 import { createColumnsDefinition } from './FilesTableColumnsDefinition'
-import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo'
 import { useFileSelection } from './row-selection/useFileSelection'
+import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo'
 
 export type RowSelection = {
   [key: string]: boolean
diff --git a/src/sections/dataset/dataset-files/useFiles.tsx b/src/sections/dataset/dataset-files/useFiles.tsx
index 538da0921..ce628deb3 100644
--- a/src/sections/dataset/dataset-files/useFiles.tsx
+++ b/src/sections/dataset/dataset-files/useFiles.tsx
@@ -5,11 +5,11 @@ import { getFilesByDatasetPersistentId } from '../../../files/domain/useCases/ge
 import { FileCriteria } from '../../../files/domain/models/FileCriteria'
 import { FilesCountInfo } from '../../../files/domain/models/FilesCountInfo'
 import { getFilesCountInfoByDatasetPersistentId } from '../../../files/domain/useCases/getFilesCountInfoByDatasetPersistentId'
-import { FilePaginationInfo } from '../../../files/domain/models/FilePaginationInfo'
 import { useFilePermissions } from '../../file/file-permissions/FilePermissionsContext'
 import { FilePermission } from '../../../files/domain/models/FileUserPermissions'
 import { DatasetVersion } from '../../../dataset/domain/models/Dataset'
 import { getFilesTotalDownloadSize } from '../../../files/domain/useCases/getFilesTotalDownloadSize'
+import { FilePaginationInfo } from '../../../files/domain/models/FilePaginationInfo'
 
 export function useFiles(
   filesRepository: FileRepository,
@@ -33,7 +33,7 @@ export function useFiles(
     )
       .then((filesCountInfo: FilesCountInfo) => {
         setFilesCountInfo(filesCountInfo)
-        if (filesCountInfo.total !== paginationInfo.totalFiles) {
+        if (filesCountInfo.total !== paginationInfo.totalItems) {
           onPaginationInfoChange(paginationInfo.withTotal(filesCountInfo.total))
         }
         return filesCountInfo
diff --git a/src/sections/dataset/dataset-icon/DatasetIcon.module.scss b/src/sections/dataset/dataset-icon/DatasetIcon.module.scss
new file mode 100644
index 000000000..4025c0bbe
--- /dev/null
+++ b/src/sections/dataset/dataset-icon/DatasetIcon.module.scss
@@ -0,0 +1,6 @@
+@import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module";
+
+.icon {
+  color: $dv-info-border-color;
+  line-height: 1.1;
+}
\ No newline at end of file
diff --git a/src/sections/dataset/dataset-icon/DatasetIcon.tsx b/src/sections/dataset/dataset-icon/DatasetIcon.tsx
new file mode 100644
index 000000000..ac68ba92b
--- /dev/null
+++ b/src/sections/dataset/dataset-icon/DatasetIcon.tsx
@@ -0,0 +1,10 @@
+import styles from './DatasetIcon.module.scss'
+import { Icon, IconName } from '@iqss/dataverse-design-system'
+
+export function DatasetIcon() {
+  return (
+    <div className={styles.icon}>
+      <Icon name={IconName.DATASET} />
+    </div>
+  )
+}
diff --git a/src/sections/dataset/dataset-thumbnail/DatasetThumbnail.module.scss b/src/sections/dataset/dataset-thumbnail/DatasetThumbnail.module.scss
new file mode 100644
index 000000000..a464f4dc4
--- /dev/null
+++ b/src/sections/dataset/dataset-thumbnail/DatasetThumbnail.module.scss
@@ -0,0 +1,6 @@
+.preview-image {
+  width: 100%;
+  max-width: 140px;
+  height: auto;
+  max-height: 140px;
+}
\ No newline at end of file
diff --git a/src/sections/dataset/dataset-thumbnail/DatasetThumbnail.tsx b/src/sections/dataset/dataset-thumbnail/DatasetThumbnail.tsx
new file mode 100644
index 000000000..628cdd8ac
--- /dev/null
+++ b/src/sections/dataset/dataset-thumbnail/DatasetThumbnail.tsx
@@ -0,0 +1,16 @@
+import styles from './DatasetThumbnail.module.scss'
+import { DatasetIcon } from '../dataset-icon/DatasetIcon'
+
+interface DatasetThumbnailProps {
+  thumbnail?: string
+  title: string
+  isDeaccessioned?: boolean
+}
+
+export function DatasetThumbnail({ thumbnail, title, isDeaccessioned }: DatasetThumbnailProps) {
+  if (thumbnail && !isDeaccessioned) {
+    return <img className={styles['preview-image']} src={thumbnail} alt={title} />
+  }
+
+  return <DatasetIcon />
+}
diff --git a/src/sections/hello-dataverse/HelloDataverse.module.scss b/src/sections/hello-dataverse/HelloDataverse.module.scss
deleted file mode 100644
index 505b1cb9c..000000000
--- a/src/sections/hello-dataverse/HelloDataverse.module.scss
+++ /dev/null
@@ -1,26 +0,0 @@
-@import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module";
-@import "src/sections/assets/variables";
-
-.container {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  min-height: $body-available-height;
-  font-size: calc(10px + 2vmin);
-  text-align: center;
-}
-
-.title {
-  color: $dv-brand-color;
-}
-
-.logo {
-  height: 40vmin;
-  pointer-events: none;
-}
-
-.link {
-  color: $dv-link-color;
-}
-
diff --git a/src/sections/hello-dataverse/HelloDataverse.tsx b/src/sections/hello-dataverse/HelloDataverse.tsx
deleted file mode 100644
index e955d0e66..000000000
--- a/src/sections/hello-dataverse/HelloDataverse.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import logo from '../assets/logo.svg'
-import styles from './HelloDataverse.module.scss'
-import { Trans, useTranslation } from 'react-i18next'
-
-export function HelloDataverse() {
-  const { t } = useTranslation('helloDataverse')
-
-  return (
-    <section className={styles.container}>
-      <h2 className={styles.title}>{t('title')}</h2>
-      <img src={logo} className={styles.logo} alt={t('altImage')} />
-      <p>
-        <Trans t={t} i18nKey="description" components={{ 1: <code /> }} />
-      </p>
-      <a
-        className={styles.link}
-        href="https://dataverse.org"
-        target="_blank"
-        rel="noopener noreferrer">
-        {t('linkText')}
-      </a>
-    </section>
-  )
-}
diff --git a/src/sections/home/Home.tsx b/src/sections/home/Home.tsx
new file mode 100644
index 000000000..803e2a1d6
--- /dev/null
+++ b/src/sections/home/Home.tsx
@@ -0,0 +1,20 @@
+import { Row } from '@iqss/dataverse-design-system'
+import { useTranslation } from 'react-i18next'
+import { DatasetRepository } from '../../dataset/domain/repositories/DatasetRepository'
+import { DatasetsList } from './datasets-list/DatasetsList'
+interface HomeProps {
+  datasetRepository: DatasetRepository
+}
+
+export function Home({ datasetRepository }: HomeProps) {
+  const { t } = useTranslation('home')
+
+  return (
+    <Row>
+      <header>
+        <h1>{t('title')}</h1>
+      </header>
+      <DatasetsList datasetRepository={datasetRepository} />
+    </Row>
+  )
+}
diff --git a/src/sections/home/HomeFactory.tsx b/src/sections/home/HomeFactory.tsx
new file mode 100644
index 000000000..f37a69caa
--- /dev/null
+++ b/src/sections/home/HomeFactory.tsx
@@ -0,0 +1,10 @@
+import { ReactElement } from 'react'
+import { Home } from './Home'
+import { DatasetJSDataverseRepository } from '../../dataset/infrastructure/repositories/DatasetJSDataverseRepository'
+
+const datasetRepository = new DatasetJSDataverseRepository()
+export class HomeFactory {
+  static create(): ReactElement {
+    return <Home datasetRepository={datasetRepository} />
+  }
+}
diff --git a/src/sections/home/datasets-list/DatasetsList.module.scss b/src/sections/home/datasets-list/DatasetsList.module.scss
new file mode 100644
index 000000000..15aff10a5
--- /dev/null
+++ b/src/sections/home/datasets-list/DatasetsList.module.scss
@@ -0,0 +1,13 @@
+@import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module";
+
+.container {
+  min-height: calc(100vh + 100px);
+  padding:15px;
+  border: 1px solid #ddd;
+  border-radius: 4px;
+}
+
+.empty-message-container {
+  padding: .5em 1em;
+  background: $dv-warning-box-color;
+}
diff --git a/src/sections/home/datasets-list/DatasetsList.tsx b/src/sections/home/datasets-list/DatasetsList.tsx
new file mode 100644
index 000000000..da13f06d3
--- /dev/null
+++ b/src/sections/home/datasets-list/DatasetsList.tsx
@@ -0,0 +1,53 @@
+import { useDatasets } from './useDatasets'
+import styles from './DatasetsList.module.scss'
+import { DatasetRepository } from '../../../dataset/domain/repositories/DatasetRepository'
+import { useEffect, useState } from 'react'
+import { PaginationResultsInfo } from '../../shared/pagination/PaginationResultsInfo'
+import { PaginationControls } from '../../shared/pagination/PaginationControls'
+import { DatasetPaginationInfo } from '../../../dataset/domain/models/DatasetPaginationInfo'
+import { useLoading } from '../../loading/LoadingContext'
+import { DatasetsListSkeleton } from './DatasetsListSkeleton'
+import { NoDatasetsMessage } from './NoDatasetsMessage'
+import { DatasetCard } from './dataset-card/DatasetCard'
+
+interface DatasetsListProps {
+  datasetRepository: DatasetRepository
+}
+const NO_DATASETS = 0
+export function DatasetsList({ datasetRepository }: DatasetsListProps) {
+  const { setIsLoading } = useLoading()
+  const [paginationInfo, setPaginationInfo] = useState<DatasetPaginationInfo>(
+    new DatasetPaginationInfo()
+  )
+  const { datasets, isLoading } = useDatasets(datasetRepository, setPaginationInfo, paginationInfo)
+
+  useEffect(() => {
+    setIsLoading(isLoading)
+  }, [isLoading])
+
+  if (isLoading) {
+    return <DatasetsListSkeleton />
+  }
+
+  return (
+    <section className={styles.container}>
+      {datasets.length === NO_DATASETS ? (
+        <NoDatasetsMessage />
+      ) : (
+        <>
+          <div>
+            <PaginationResultsInfo paginationInfo={paginationInfo} />
+          </div>
+          {datasets.map((dataset) => (
+            <DatasetCard dataset={dataset} key={dataset.persistentId} />
+          ))}
+          <PaginationControls
+            onPaginationInfoChange={setPaginationInfo}
+            initialPaginationInfo={paginationInfo}
+            showPageSizeSelector={false}
+          />
+        </>
+      )}
+    </section>
+  )
+}
diff --git a/src/sections/home/datasets-list/DatasetsListSkeleton.tsx b/src/sections/home/datasets-list/DatasetsListSkeleton.tsx
new file mode 100644
index 000000000..b07bc39d3
--- /dev/null
+++ b/src/sections/home/datasets-list/DatasetsListSkeleton.tsx
@@ -0,0 +1,26 @@
+import styles from './DatasetsList.module.scss'
+import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'
+
+export function DatasetsListSkeleton() {
+  return (
+    <SkeletonTheme>
+      <section className={styles.container} data-testid="datasets-list-skeleton">
+        <div>
+          <Skeleton width="14%" />
+        </div>
+        <article>
+          <Skeleton height="109px" style={{ marginBottom: 6 }} />
+          <Skeleton height="109px" style={{ marginBottom: 6 }} />
+          <Skeleton height="109px" style={{ marginBottom: 6 }} />
+          <Skeleton height="109px" style={{ marginBottom: 6 }} />
+          <Skeleton height="109px" style={{ marginBottom: 6 }} />
+          <Skeleton height="109px" style={{ marginBottom: 6 }} />
+          <Skeleton height="109px" style={{ marginBottom: 6 }} />
+          <Skeleton height="109px" style={{ marginBottom: 6 }} />
+          <Skeleton height="109px" style={{ marginBottom: 6 }} />
+          <Skeleton height="109px" style={{ marginBottom: 6 }} />
+        </article>
+      </section>
+    </SkeletonTheme>
+  )
+}
diff --git a/src/sections/home/datasets-list/NoDatasetsMessage.tsx b/src/sections/home/datasets-list/NoDatasetsMessage.tsx
new file mode 100644
index 000000000..a7ad3cfc0
--- /dev/null
+++ b/src/sections/home/datasets-list/NoDatasetsMessage.tsx
@@ -0,0 +1,24 @@
+import styles from './DatasetsList.module.scss'
+import { Trans, useTranslation } from 'react-i18next'
+import { useSession } from '../../session/SessionContext'
+import { Route } from '../../Route.enum'
+
+export function NoDatasetsMessage() {
+  const { t } = useTranslation('home')
+  const { user } = useSession()
+
+  return (
+    <div className={styles['empty-message-container']}>
+      {user ? (
+        <p>{t('noDatasetsMessage.authenticated')}</p>
+      ) : (
+        <Trans i18nKey="noDatasetsMessage.anonymous">
+          <p>
+            This dataverse currently has no datasets. Please <a href={Route.LOG_IN}>log in</a> to
+            see if you are able to add to it.
+          </p>
+        </Trans>
+      )}
+    </div>
+  )
+}
diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCard.module.scss b/src/sections/home/datasets-list/dataset-card/DatasetCard.module.scss
new file mode 100644
index 000000000..92f7696b2
--- /dev/null
+++ b/src/sections/home/datasets-list/dataset-card/DatasetCard.module.scss
@@ -0,0 +1,71 @@
+@use 'sass:color';
+@import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module";
+@import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/typography.module";
+
+.container {
+  margin: 6px 0;
+  padding: 4px 10px;
+  border: 1px solid $dv-info-border-color;
+}
+
+.header {
+  display: flex;
+  justify-content: space-between;
+}
+
+.title {
+  display: flex;
+
+  > * {
+    margin-right: .5em;
+  }
+}
+
+.icon {
+  margin-top: 2px;
+  font-size: 1.3em;
+
+  > div >span {
+    margin-right: 0;
+  }
+}
+
+.thumbnail {
+  width: 48px;
+  margin: 8px 12px 6px 0;
+  font-size: 2.8em;
+
+  img {
+      vertical-align: top;
+  }
+}
+
+.info {
+  display: flex;
+}
+
+.description {
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+  font-size: $dv-font-size-sm;
+}
+
+.date {
+  color: $dv-subtext-color;
+
+}
+
+.citation-box {
+  margin-top: 4px;
+  margin-bottom: .5em;
+  padding: 4px;
+  background-color: color.adjust($dv-primary-color, $lightness: 51%) ;
+}
+
+.citation-box-deaccessioned {
+  margin-top: 4px;
+  margin-bottom: .5em;
+  padding: 4px;
+  background-color: color.adjust($dv-danger-box-color, $lightness: 6%);
+}
\ No newline at end of file
diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCard.tsx b/src/sections/home/datasets-list/dataset-card/DatasetCard.tsx
new file mode 100644
index 000000000..6fe1f807e
--- /dev/null
+++ b/src/sections/home/datasets-list/dataset-card/DatasetCard.tsx
@@ -0,0 +1,21 @@
+import { DatasetPreview } from '../../../../dataset/domain/models/DatasetPreview'
+import styles from './DatasetCard.module.scss'
+import { DatasetCardHeader } from './DatasetCardHeader'
+import { DatasetCardThumbnail } from './DatasetCardThumbnail'
+import { DatasetCardInfo } from './DatasetCardInfo'
+
+interface DatasetCardProps {
+  dataset: DatasetPreview
+}
+
+export function DatasetCard({ dataset }: DatasetCardProps) {
+  return (
+    <article className={styles.container}>
+      <DatasetCardHeader dataset={dataset} />
+      <div className={styles.info}>
+        <DatasetCardThumbnail dataset={dataset} />
+        <DatasetCardInfo dataset={dataset} />
+      </div>
+    </article>
+  )
+}
diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCardHeader.tsx b/src/sections/home/datasets-list/dataset-card/DatasetCardHeader.tsx
new file mode 100644
index 000000000..9e927b2fc
--- /dev/null
+++ b/src/sections/home/datasets-list/dataset-card/DatasetCardHeader.tsx
@@ -0,0 +1,25 @@
+import styles from './DatasetCard.module.scss'
+import { LinkToPage } from '../../../shared/link-to-page/LinkToPage'
+import { Route } from '../../../Route.enum'
+import { DatasetLabels } from '../../../dataset/dataset-labels/DatasetLabels'
+import { DatasetPreview } from '../../../../dataset/domain/models/DatasetPreview'
+import { DatasetIcon } from '../../../dataset/dataset-icon/DatasetIcon'
+
+interface DatasetCardHeaderProps {
+  dataset: DatasetPreview
+}
+export function DatasetCardHeader({ dataset }: DatasetCardHeaderProps) {
+  return (
+    <div className={styles.header}>
+      <div className={styles.title}>
+        <LinkToPage page={Route.DATASETS} searchParams={{ persistentId: dataset.persistentId }}>
+          {dataset.title}
+        </LinkToPage>
+        <DatasetLabels labels={dataset.labels} />
+      </div>
+      <div className={styles.icon}>
+        <DatasetIcon />
+      </div>
+    </div>
+  )
+}
diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCardInfo.tsx b/src/sections/home/datasets-list/dataset-card/DatasetCardInfo.tsx
new file mode 100644
index 000000000..76a03a645
--- /dev/null
+++ b/src/sections/home/datasets-list/dataset-card/DatasetCardInfo.tsx
@@ -0,0 +1,23 @@
+import styles from './DatasetCard.module.scss'
+import { DateHelper } from '../../../../shared/domain/helpers/DateHelper'
+import { DatasetPreview } from '../../../../dataset/domain/models/DatasetPreview'
+import { CitationDescription } from '../../../shared/citation/CitationDescription'
+
+interface DatasetCardInfoProps {
+  dataset: DatasetPreview
+}
+
+export function DatasetCardInfo({ dataset }: DatasetCardInfoProps) {
+  return (
+    <div className={styles.description}>
+      <span className={styles.date}>{DateHelper.toDisplayFormat(dataset.releaseOrCreateDate)}</span>
+      <span
+        className={
+          dataset.isDeaccessioned ? styles['citation-box-deaccessioned'] : styles['citation-box']
+        }>
+        <CitationDescription citation={dataset.citation} />
+      </span>
+      <span>{dataset.abbreviatedDescription}</span>
+    </div>
+  )
+}
diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.tsx b/src/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.tsx
new file mode 100644
index 000000000..cba65b215
--- /dev/null
+++ b/src/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.tsx
@@ -0,0 +1,23 @@
+import styles from './DatasetCard.module.scss'
+import { DatasetPreview } from '../../../../dataset/domain/models/DatasetPreview'
+import { LinkToPage } from '../../../shared/link-to-page/LinkToPage'
+import { Route } from '../../../Route.enum'
+import { DatasetThumbnail } from '../../../dataset/dataset-thumbnail/DatasetThumbnail'
+
+interface DatasetCardThumbnailProps {
+  dataset: DatasetPreview
+}
+
+export function DatasetCardThumbnail({ dataset }: DatasetCardThumbnailProps) {
+  return (
+    <div className={styles.thumbnail}>
+      <LinkToPage page={Route.DATASETS} searchParams={{ persistentId: dataset.persistentId }}>
+        <DatasetThumbnail
+          title={dataset.title}
+          thumbnail={dataset.thumbnail}
+          isDeaccessioned={dataset.isDeaccessioned}
+        />
+      </LinkToPage>
+    </div>
+  )
+}
diff --git a/src/sections/home/datasets-list/useDatasets.tsx b/src/sections/home/datasets-list/useDatasets.tsx
new file mode 100644
index 000000000..8bb900423
--- /dev/null
+++ b/src/sections/home/datasets-list/useDatasets.tsx
@@ -0,0 +1,65 @@
+import { useEffect, useState } from 'react'
+import { DatasetRepository } from '../../../dataset/domain/repositories/DatasetRepository'
+import { getDatasets } from '../../../dataset/domain/useCases/getDatasets'
+import { getTotalDatasetsCount } from '../../../dataset/domain/useCases/getTotalDatasetsCount'
+import { TotalDatasetsCount } from '../../../dataset/domain/models/TotalDatasetsCount'
+import { DatasetPaginationInfo } from '../../../dataset/domain/models/DatasetPaginationInfo'
+import { DatasetPreview } from '../../../dataset/domain/models/DatasetPreview'
+
+export function useDatasets(
+  datasetRepository: DatasetRepository,
+  onPaginationInfoChange: (paginationInfo: DatasetPaginationInfo) => void,
+  paginationInfo: DatasetPaginationInfo
+) {
+  const [datasets, setDatasets] = useState<DatasetPreview[]>([])
+  const [isLoading, setIsLoading] = useState<boolean>(true)
+  const [totalDatasetsCount, setTotalDatasetsCount] = useState<TotalDatasetsCount>()
+
+  const fetchTotalDatasetsCount: () => Promise<TotalDatasetsCount> = () => {
+    return getTotalDatasetsCount(datasetRepository)
+      .then((totalDatasetsCount: TotalDatasetsCount) => {
+        setTotalDatasetsCount(totalDatasetsCount)
+        if (totalDatasetsCount !== paginationInfo.totalItems) {
+          onPaginationInfoChange(paginationInfo.withTotal(totalDatasetsCount))
+        }
+        return totalDatasetsCount
+      })
+      .catch(() => {
+        throw new Error('There was an error getting the datasets count info')
+      })
+  }
+  const fetchDatasets = (totalDatasetsCount: TotalDatasetsCount) => {
+    if (typeof totalDatasetsCount !== 'undefined') {
+      if (totalDatasetsCount === 0) {
+        setIsLoading(false)
+        return
+      }
+      return getDatasets(datasetRepository, paginationInfo.withTotal(totalDatasetsCount))
+        .then((datasets: DatasetPreview[]) => {
+          setDatasets(datasets)
+          setIsLoading(false)
+          return datasets
+        })
+        .catch(() => {
+          throw new Error('There was an error getting the datasets')
+        })
+    }
+  }
+
+  useEffect(() => {
+    setIsLoading(true)
+
+    fetchTotalDatasetsCount()
+      .then((totalDatasetsCount) => fetchDatasets(totalDatasetsCount))
+      .catch(() => {
+        console.error('There was an error getting the datasets')
+        setIsLoading(false)
+      })
+  }, [datasetRepository, paginationInfo.page])
+
+  return {
+    datasets,
+    totalDatasetsCount,
+    isLoading
+  }
+}
diff --git a/src/sections/layout/header/Header.tsx b/src/sections/layout/header/Header.tsx
index e83b454be..7121bd1f1 100644
--- a/src/sections/layout/header/Header.tsx
+++ b/src/sections/layout/header/Header.tsx
@@ -3,22 +3,31 @@ import { useTranslation } from 'react-i18next'
 import { Navbar } from '@iqss/dataverse-design-system'
 import { Route } from '../../Route.enum'
 import { useSession } from '../../session/SessionContext'
+import { useNavigate } from 'react-router-dom'
 
+const currentPage = 0
 export function Header() {
   const { t } = useTranslation('header')
   const { user, logout } = useSession()
+  const navigate = useNavigate()
   const baseRemoteUrl = import.meta.env.VITE_DATAVERSE_BACKEND_URL as string
 
+  const onLogoutClick = () => {
+    void logout().then(() => {
+      navigate(currentPage)
+    })
+  }
+
   return (
     <Navbar
       brand={{
         title: t('brandTitle'),
-        href: Route.HOME,
+        href: `/spa${Route.HOME}`,
         logoImgSrc: logo
       }}>
       {user ? (
         <Navbar.Dropdown title={user.name} id="dropdown-user">
-          <Navbar.Dropdown.Item href={Route.LOG_OUT} onClick={logout}>
+          <Navbar.Dropdown.Item href="#" onClick={onLogoutClick}>
             {t('logOut')}
           </Navbar.Dropdown.Item>
         </Navbar.Dropdown>
diff --git a/src/sections/session/SessionContext.ts b/src/sections/session/SessionContext.ts
index 4840d510a..5bafb77cf 100644
--- a/src/sections/session/SessionContext.ts
+++ b/src/sections/session/SessionContext.ts
@@ -4,12 +4,12 @@ import { User } from '../../users/domain/models/User'
 interface SessionContextProps {
   user: User | null
   setUser: (user: User) => void
-  logout: () => void
+  logout: () => Promise<void>
 }
 export const SessionContext = createContext<SessionContextProps>({
   user: null,
   setUser: () => {},
-  logout: () => {}
+  logout: () => Promise.resolve()
 })
 
 export const useSession = () => useContext(SessionContext)
diff --git a/src/sections/session/SessionProvider.tsx b/src/sections/session/SessionProvider.tsx
index 56fa07d81..4fb95b74b 100644
--- a/src/sections/session/SessionProvider.tsx
+++ b/src/sections/session/SessionProvider.tsx
@@ -20,7 +20,7 @@ export function SessionProvider({ repository, children }: PropsWithChildren<Sess
   }, [repository])
 
   const submitLogOut = () => {
-    logOut(repository)
+    return logOut(repository)
       .then(() => {
         setUser(null)
       })
diff --git a/src/sections/shared/citation/CitationDescription.tsx b/src/sections/shared/citation/CitationDescription.tsx
new file mode 100644
index 000000000..eb2730bd2
--- /dev/null
+++ b/src/sections/shared/citation/CitationDescription.tsx
@@ -0,0 +1,11 @@
+import parse from 'html-react-parser'
+
+interface CitationDescriptionProps {
+  citation: string
+}
+
+export function CitationDescription({ citation }: CitationDescriptionProps) {
+  const citationAsReactElement = parse(citation)
+
+  return <span>{citationAsReactElement}</span>
+}
diff --git a/src/sections/shared/link-to-page/LinkToPage.tsx b/src/sections/shared/link-to-page/LinkToPage.tsx
new file mode 100644
index 000000000..dd38a28af
--- /dev/null
+++ b/src/sections/shared/link-to-page/LinkToPage.tsx
@@ -0,0 +1,20 @@
+import { Link } from 'react-router-dom'
+import { PropsWithChildren } from 'react'
+import { Route } from '../../Route.enum'
+
+interface LinkToPageProps {
+  page: Route
+  searchParams?: Record<string, string>
+}
+
+export function LinkToPage({ children, page, searchParams }: PropsWithChildren<LinkToPageProps>) {
+  const searchParamsString: string = searchParams ? '?' + encodeSearchParamsToURI(searchParams) : ''
+
+  return <Link to={`${page}${searchParamsString}`}>{children}</Link>
+}
+
+const encodeSearchParamsToURI = (searchParams: Record<string, string>) => {
+  return Object.entries(searchParams)
+    .map(([key, value]) => `${key}=${value}`)
+    .join('&')
+}
diff --git a/src/sections/dataset/dataset-files/files-pagination/PageNumbersButtons.tsx b/src/sections/shared/pagination/PageNumbersButtons.tsx
similarity index 100%
rename from src/sections/dataset/dataset-files/files-pagination/PageNumbersButtons.tsx
rename to src/sections/shared/pagination/PageNumbersButtons.tsx
diff --git a/src/sections/dataset/dataset-files/files-pagination/PageNumbersButtonsWithEllipsis.tsx b/src/sections/shared/pagination/PageNumbersButtonsWithEllipsis.tsx
similarity index 100%
rename from src/sections/dataset/dataset-files/files-pagination/PageNumbersButtonsWithEllipsis.tsx
rename to src/sections/shared/pagination/PageNumbersButtonsWithEllipsis.tsx
diff --git a/src/sections/dataset/dataset-files/files-pagination/PageSizeSelector.tsx b/src/sections/shared/pagination/PageSizeSelector.tsx
similarity index 80%
rename from src/sections/dataset/dataset-files/files-pagination/PageSizeSelector.tsx
rename to src/sections/shared/pagination/PageSizeSelector.tsx
index a5acbf945..2378453df 100644
--- a/src/sections/dataset/dataset-files/files-pagination/PageSizeSelector.tsx
+++ b/src/sections/shared/pagination/PageSizeSelector.tsx
@@ -1,20 +1,24 @@
-import styles from './FilesPagination.module.scss'
+import styles from './Pagination.module.scss'
 import { useTranslation } from 'react-i18next'
 
 export function PageSizeSelector({
+  itemName,
   pageSize,
   setPageSize
 }: {
+  itemName: string
   pageSize: number
   setPageSize: (pageSize: number) => void
 }) {
-  const { t } = useTranslation('files')
+  const { t } = useTranslation('pagination')
   const availableSizes = [10, 25, 50]
 
   return (
     <div className={styles['size-selector-container']}>
       <label htmlFor="files-per-page-selector" className={styles['size-selector-container__text']}>
-        {t('table.pagination.pageSize')}
+        {t('pageSize', {
+          item: itemName
+        })}
       </label>
       <select
         id="files-per-page-selector"
diff --git a/src/sections/dataset/dataset-files/files-pagination/FilesPagination.module.scss b/src/sections/shared/pagination/Pagination.module.scss
similarity index 55%
rename from src/sections/dataset/dataset-files/files-pagination/FilesPagination.module.scss
rename to src/sections/shared/pagination/Pagination.module.scss
index f75206577..c5b97fb62 100644
--- a/src/sections/dataset/dataset-files/files-pagination/FilesPagination.module.scss
+++ b/src/sections/shared/pagination/Pagination.module.scss
@@ -1,3 +1,5 @@
+@import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/typography.module";
+
 .row {
   justify-content: center;
 }
@@ -15,4 +17,9 @@
   &__text {
     margin-right: 14px;
   }
+}
+
+.results {
+  margin-right: 4px;
+  font-weight: $dv-font-weight-bold;
 }
\ No newline at end of file
diff --git a/src/sections/dataset/dataset-files/files-pagination/FilesPagination.tsx b/src/sections/shared/pagination/PaginationControls.tsx
similarity index 62%
rename from src/sections/dataset/dataset-files/files-pagination/FilesPagination.tsx
rename to src/sections/shared/pagination/PaginationControls.tsx
index 7a6c3c976..834b19842 100644
--- a/src/sections/dataset/dataset-files/files-pagination/FilesPagination.tsx
+++ b/src/sections/shared/pagination/PaginationControls.tsx
@@ -1,25 +1,27 @@
 import { Col, Pagination, Row } from '@iqss/dataverse-design-system'
 import { PageNumbersButtonsWithEllipsis } from './PageNumbersButtonsWithEllipsis'
 import { PageSizeSelector } from './PageSizeSelector'
-import styles from './FilesPagination.module.scss'
-import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo'
+import styles from './Pagination.module.scss'
+import { PaginationInfo } from '../../../shared/domain/models/PaginationInfo'
 import { useEffect, useState } from 'react'
+import { FilePaginationInfo } from '../../../files/domain/models/FilePaginationInfo'
+import { DatasetPaginationInfo } from '../../../dataset/domain/models/DatasetPaginationInfo'
 
-interface FilesPaginationProps {
-  onPaginationInfoChange: (paginationInfo: FilePaginationInfo) => void
-  page: number
-  pageSize: number
-  total: number
+interface PaginationProps {
+  onPaginationInfoChange: (
+    paginationInfo: PaginationInfo<DatasetPaginationInfo | FilePaginationInfo>
+  ) => void
+  initialPaginationInfo: PaginationInfo<DatasetPaginationInfo | FilePaginationInfo>
+  showPageSizeSelector?: boolean
 }
 const NO_PAGES = 0
-export function FilesPagination({
+export function PaginationControls({
   onPaginationInfoChange,
-  page,
-  pageSize,
-  total
-}: FilesPaginationProps) {
-  const [paginationInfo, setPaginationInfo] = useState<FilePaginationInfo>(
-    new FilePaginationInfo(page, pageSize, total)
+  initialPaginationInfo,
+  showPageSizeSelector = true
+}: PaginationProps) {
+  const [paginationInfo, setPaginationInfo] = useState<DatasetPaginationInfo | FilePaginationInfo>(
+    initialPaginationInfo
   )
   const goToPage = (newPage: number) => {
     setPaginationInfo(paginationInfo.goToPage(newPage))
@@ -39,8 +41,8 @@ export function FilesPagination({
   }, [paginationInfo.pageSize, paginationInfo.page])
 
   useEffect(() => {
-    setPaginationInfo(paginationInfo.withTotal(total))
-  }, [total])
+    setPaginationInfo(paginationInfo.withTotal(initialPaginationInfo.totalItems))
+  }, [initialPaginationInfo.totalItems])
 
   if (paginationInfo.totalPages === NO_PAGES) {
     return <></>
@@ -72,7 +74,13 @@ export function FilesPagination({
               disabled={!paginationInfo.hasNextPage}
             />
           </Pagination>
-          <PageSizeSelector pageSize={paginationInfo.pageSize} setPageSize={setPageSize} />
+          {showPageSizeSelector && (
+            <PageSizeSelector
+              itemName={paginationInfo.itemName}
+              pageSize={paginationInfo.pageSize}
+              setPageSize={setPageSize}
+            />
+          )}
         </div>
       </Col>
     </Row>
diff --git a/src/sections/shared/pagination/PaginationResultsInfo.tsx b/src/sections/shared/pagination/PaginationResultsInfo.tsx
new file mode 100644
index 000000000..df57ad701
--- /dev/null
+++ b/src/sections/shared/pagination/PaginationResultsInfo.tsx
@@ -0,0 +1,23 @@
+import styles from './Pagination.module.scss'
+import { PaginationInfo } from '../../../shared/domain/models/PaginationInfo'
+import { useTranslation } from 'react-i18next'
+import { DatasetPaginationInfo } from '../../../dataset/domain/models/DatasetPaginationInfo'
+import { FilePaginationInfo } from '../../../files/domain/models/FilePaginationInfo'
+
+interface PaginationResultsInfoProps {
+  paginationInfo: PaginationInfo<DatasetPaginationInfo | FilePaginationInfo>
+}
+
+export function PaginationResultsInfo({ paginationInfo }: PaginationResultsInfoProps) {
+  const { t } = useTranslation('pagination')
+  return (
+    <span className={styles.results}>
+      {t('results', {
+        start: paginationInfo.pageStartItem,
+        end: paginationInfo.pageEndItem,
+        total: paginationInfo.totalItems,
+        item: paginationInfo.itemName
+      })}
+    </span>
+  )
+}
diff --git a/src/shared/domain/helpers/DateHelper.ts b/src/shared/domain/helpers/DateHelper.ts
new file mode 100644
index 000000000..021ec2a68
--- /dev/null
+++ b/src/shared/domain/helpers/DateHelper.ts
@@ -0,0 +1,9 @@
+export class DateHelper {
+  static toDisplayFormat(date: Date): string {
+    return date.toLocaleDateString(Intl.DateTimeFormat().resolvedOptions().locale, {
+      year: 'numeric',
+      month: 'short',
+      day: 'numeric'
+    })
+  }
+}
diff --git a/src/shared/domain/models/PaginationInfo.ts b/src/shared/domain/models/PaginationInfo.ts
new file mode 100644
index 000000000..c21822b7c
--- /dev/null
+++ b/src/shared/domain/models/PaginationInfo.ts
@@ -0,0 +1,72 @@
+export class PaginationInfo<T extends PaginationInfo<T>> {
+  constructor(
+    public readonly page: number = 1,
+    public readonly pageSize: number = 10,
+    public readonly totalItems: number = 0,
+    public readonly itemName: string = 'Item'
+  ) {}
+
+  get offset(): number {
+    return (this.page - 1) * this.pageSize
+  }
+
+  get pageStartItem(): number {
+    return (this.page - 1) * this.pageSize + 1
+  }
+
+  get pageEndItem(): number {
+    return Math.min(this.pageStartItem + this.pageSize - 1, this.totalItems)
+  }
+
+  withTotal(total: number): T {
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    return new (this.constructor as new (...args: any[]) => T)(this.page, this.pageSize, total)
+  }
+  goToPage(page: number): T {
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    return new (this.constructor as new (...args: any[]) => T)(page, this.pageSize, this.totalItems)
+  }
+
+  goToPreviousPage(): T {
+    if (!this.previousPage) throw new Error('No previous page')
+    return this.goToPage(this.previousPage)
+  }
+
+  goToNextPage(): T {
+    if (!this.nextPage) throw new Error('No next page')
+    return this.goToPage(this.nextPage)
+  }
+
+  withPageSize(pageSize: number): T {
+    const getNewPage = (oldPageSize: number, newPageSize: number) => {
+      const newPage = Math.ceil(((this.page - 1) * oldPageSize + 1) / newPageSize)
+      return newPage > 0 ? newPage : 1
+    }
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    return new (this.constructor as new (...args: any[]) => T)(
+      getNewPage(this.pageSize, pageSize),
+      pageSize,
+      this.totalItems
+    )
+  }
+
+  get totalPages(): number {
+    return Math.ceil(this.totalItems / this.pageSize)
+  }
+
+  get hasPreviousPage(): boolean {
+    return this.page > 1
+  }
+
+  get hasNextPage(): boolean {
+    return this.page < this.totalPages
+  }
+
+  get previousPage(): number | undefined {
+    return this.hasPreviousPage ? this.page - 1 : undefined
+  }
+
+  get nextPage(): number | undefined {
+    return this.hasNextPage ? this.page + 1 : undefined
+  }
+}
diff --git a/src/stories/WithLayout.tsx b/src/stories/WithLayout.tsx
index 2dc1dcc0d..34a5af36d 100644
--- a/src/stories/WithLayout.tsx
+++ b/src/stories/WithLayout.tsx
@@ -1,16 +1,14 @@
 import { StoryFn } from '@storybook/react'
-import { MemoryRouter as Router, Routes, Route } from 'react-router-dom'
+import { Routes, Route } from 'react-router-dom'
 import { Layout } from '../sections/layout/Layout'
 import { LoadingProvider } from '../sections/loading/LoadingProvider'
 
 export const WithLayout = (Story: StoryFn) => (
   <LoadingProvider>
-    <Router>
-      <Routes>
-        <Route element={<Layout />}>
-          <Route path="/*" element={<Story />} />
-        </Route>
-      </Routes>
-    </Router>
+    <Routes>
+      <Route element={<Layout />}>
+        <Route path="/*" element={<Story />} />
+      </Route>
+    </Routes>
   </LoadingProvider>
 )
diff --git a/src/stories/WithLoggedInUser.tsx b/src/stories/WithLoggedInUser.tsx
index 75a5878a4..233c46e6f 100644
--- a/src/stories/WithLoggedInUser.tsx
+++ b/src/stories/WithLoggedInUser.tsx
@@ -5,7 +5,7 @@ import { UserMother } from '../../tests/component/users/domain/models/UserMother
 export const WithLoggedInUser = (Story: StoryFn) => {
   return (
     <SessionContext.Provider
-      value={{ user: UserMother.create(), logout: () => {}, setUser: () => {} }}>
+      value={{ user: UserMother.create(), logout: () => Promise.resolve(), setUser: () => {} }}>
       <Story />
     </SessionContext.Provider>
   )
diff --git a/src/stories/dataset/DatasetLoadingMockRepository.ts b/src/stories/dataset/DatasetLoadingMockRepository.ts
new file mode 100644
index 000000000..b7051afc7
--- /dev/null
+++ b/src/stories/dataset/DatasetLoadingMockRepository.ts
@@ -0,0 +1,10 @@
+import { DatasetMockRepository } from './DatasetMockRepository'
+import { DatasetPaginationInfo } from '../../dataset/domain/models/DatasetPaginationInfo'
+import { DatasetPreview } from '../../dataset/domain/models/DatasetPreview'
+
+export class DatasetLoadingMockRepository extends DatasetMockRepository {
+  // eslint-disable-next-line unused-imports/no-unused-vars
+  getAll(paginationInfo: DatasetPaginationInfo): Promise<DatasetPreview[]> {
+    return new Promise(() => {})
+  }
+}
diff --git a/src/stories/dataset/DatasetMockRepository.ts b/src/stories/dataset/DatasetMockRepository.ts
new file mode 100644
index 000000000..9ffa083ed
--- /dev/null
+++ b/src/stories/dataset/DatasetMockRepository.ts
@@ -0,0 +1,49 @@
+import { Dataset } from '../../dataset/domain/models/Dataset'
+import { DatasetRepository } from '../../dataset/domain/repositories/DatasetRepository'
+import { DatasetMother } from '../../../tests/component/dataset/domain/models/DatasetMother'
+import { TotalDatasetsCount } from '../../dataset/domain/models/TotalDatasetsCount'
+import { DatasetPaginationInfo } from '../../dataset/domain/models/DatasetPaginationInfo'
+import { DatasetPreview } from '../../dataset/domain/models/DatasetPreview'
+import { DatasetPreviewMother } from '../../../tests/component/dataset/domain/models/DatasetPreviewMother'
+
+export class DatasetMockRepository implements DatasetRepository {
+  // eslint-disable-next-line unused-imports/no-unused-vars
+  getAll(paginationInfo: DatasetPaginationInfo): Promise<DatasetPreview[]> {
+    return new Promise((resolve) => {
+      setTimeout(() => {
+        resolve(DatasetPreviewMother.createManyRealistic(paginationInfo.pageSize))
+      }, 1000)
+    })
+  }
+
+  getTotalDatasetsCount(): Promise<TotalDatasetsCount> {
+    return new Promise((resolve) => {
+      setTimeout(() => {
+        resolve(200)
+      }, 1000)
+    })
+  }
+
+  getByPersistentId(
+    // eslint-disable-next-line unused-imports/no-unused-vars
+    persistentId: string,
+    // eslint-disable-next-line unused-imports/no-unused-vars
+    version?: string | undefined
+  ): Promise<Dataset | undefined> {
+    return new Promise((resolve) => {
+      setTimeout(() => {
+        resolve(DatasetMother.createRealistic())
+      }, 1000)
+    })
+  }
+  getByPrivateUrlToken(
+    // eslint-disable-next-line unused-imports/no-unused-vars
+    privateUrlToken: string
+  ): Promise<Dataset | undefined> {
+    return new Promise((resolve) => {
+      setTimeout(() => {
+        resolve(DatasetMother.createRealistic())
+      }, 1000)
+    })
+  }
+}
diff --git a/src/stories/dataset/NoDatasetsMockRepository.ts b/src/stories/dataset/NoDatasetsMockRepository.ts
new file mode 100644
index 000000000..b5fa7b41c
--- /dev/null
+++ b/src/stories/dataset/NoDatasetsMockRepository.ts
@@ -0,0 +1,22 @@
+import { DatasetMockRepository } from './DatasetMockRepository'
+import { DatasetPaginationInfo } from '../../dataset/domain/models/DatasetPaginationInfo'
+import { DatasetPreview } from '../../dataset/domain/models/DatasetPreview'
+import { TotalDatasetsCount } from '../../dataset/domain/models/TotalDatasetsCount'
+export class NoDatasetsMockRepository extends DatasetMockRepository {
+  // eslint-disable-next-line unused-imports/no-unused-vars
+  getAll(paginationInfo: DatasetPaginationInfo): Promise<DatasetPreview[]> {
+    return new Promise((resolve) => {
+      setTimeout(() => {
+        resolve([])
+      }, 1000)
+    })
+  }
+
+  getTotalDatasetsCount(): Promise<TotalDatasetsCount> {
+    return new Promise((resolve) => {
+      setTimeout(() => {
+        resolve(0)
+      }, 1000)
+    })
+  }
+}
diff --git a/src/stories/dataset/WithDataset.tsx b/src/stories/dataset/WithDataset.tsx
index 6c1df0ddf..b559c9532 100644
--- a/src/stories/dataset/WithDataset.tsx
+++ b/src/stories/dataset/WithDataset.tsx
@@ -1,23 +1,10 @@
 import { StoryFn } from '@storybook/react'
 import { DatasetProvider } from '../../sections/dataset/DatasetProvider'
 import { DatasetRepository } from '../../dataset/domain/repositories/DatasetRepository'
-import { Dataset } from '../../dataset/domain/models/Dataset'
-import { DatasetMother } from '../../../tests/component/dataset/domain/models/DatasetMother'
+import { DatasetMockRepository } from './DatasetMockRepository'
 
 export const WithDataset = (Story: StoryFn) => {
-  const datasetRepository = {} as DatasetRepository
-  datasetRepository.getByPersistentId = (
-    // eslint-disable-next-line unused-imports/no-unused-vars
-    persistentId: string,
-    // eslint-disable-next-line unused-imports/no-unused-vars
-    version?: string | undefined
-  ): Promise<Dataset | undefined> => {
-    return new Promise((resolve) => {
-      setTimeout(() => {
-        resolve(DatasetMother.createRealistic())
-      }, 1000)
-    })
-  }
+  const datasetRepository: DatasetRepository = new DatasetMockRepository()
   return (
     <DatasetProvider
       repository={datasetRepository}
diff --git a/src/stories/dataset/dataset-citation/DatasetCitation.stories.tsx b/src/stories/dataset/dataset-citation/DatasetCitation.stories.tsx
index cd7d511d4..0a52d5264 100644
--- a/src/stories/dataset/dataset-citation/DatasetCitation.stories.tsx
+++ b/src/stories/dataset/dataset-citation/DatasetCitation.stories.tsx
@@ -22,7 +22,7 @@ export const Default: Story = {
         <br></br>
         <br></br>
         <DatasetCitation
-          title={dataset.getTitle()}
+          title={dataset.title}
           citation={dataset.citation}
           version={dataset.version}
         />
@@ -39,7 +39,7 @@ export const WithThumbnail: Story = {
         <br></br>
         <br></br>
         <DatasetCitation
-          title={dataset.getTitle()}
+          title={dataset.title}
           thumbnail={dataset.thumbnail}
           citation={dataset.citation}
           version={dataset.version}
@@ -71,7 +71,7 @@ export const DraftVersion: Story = {
         <br></br>
         <br></br>
         <DatasetCitation
-          title={dataset.getTitle()}
+          title={dataset.title}
           citation={dataset.citation}
           version={dataset.version}
         />
@@ -104,7 +104,7 @@ export const Deaccessioned: Story = {
         <br></br>
         <br></br>
         <DatasetCitation
-          title={dataset.getTitle()}
+          title={dataset.title}
           citation={dataset.citation}
           version={dataset.version}
         />
@@ -128,7 +128,7 @@ export const Anonymized: Story = {
         <br></br>
         <br></br>
         <DatasetCitation
-          title={dataset.getTitle()}
+          title={dataset.title}
           citation={dataset.citation}
           version={dataset.version}
         />
diff --git a/src/stories/dataset/dataset-files/files-pagination/FilesPagination.stories.tsx b/src/stories/dataset/dataset-files/files-pagination/FilesPagination.stories.tsx
deleted file mode 100644
index b090683ab..000000000
--- a/src/stories/dataset/dataset-files/files-pagination/FilesPagination.stories.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { Meta, StoryObj } from '@storybook/react'
-import { WithI18next } from '../../../WithI18next'
-import { FilesPagination } from '../../../../sections/dataset/dataset-files/files-pagination/FilesPagination'
-
-const meta: Meta<typeof FilesPagination> = {
-  title: 'Sections/Dataset Page/DatasetFiles/FilesPagination',
-  component: FilesPagination,
-  decorators: [WithI18next]
-}
-
-export default meta
-type Story = StoryObj<typeof FilesPagination>
-
-const emptyFunction = () => {}
-export const Default: Story = {
-  render: () => (
-    <FilesPagination page={10} pageSize={10} total={200} onPaginationInfoChange={emptyFunction} />
-  )
-}
-
-export const NoEllipsis: Story = {
-  render: () => (
-    <FilesPagination page={1} pageSize={10} total={100} onPaginationInfoChange={emptyFunction} />
-  )
-}
diff --git a/src/stories/files/FileMockRepository.ts b/src/stories/files/FileMockRepository.ts
index 317facbc4..020d15199 100644
--- a/src/stories/files/FileMockRepository.ts
+++ b/src/stories/files/FileMockRepository.ts
@@ -3,11 +3,11 @@ import { FilesMockData } from './FileMockData'
 import { File, FileDownloadMode } from '../../files/domain/models/File'
 import { FilesCountInfo } from '../../files/domain/models/FilesCountInfo'
 import { FilesCountInfoMother } from '../../../tests/component/files/domain/models/FilesCountInfoMother'
-import { FilePaginationInfo } from '../../files/domain/models/FilePaginationInfo'
 import { FileUserPermissionsMother } from '../../../tests/component/files/domain/models/FileUserPermissionsMother'
 import { FileUserPermissions } from '../../files/domain/models/FileUserPermissions'
 import { DatasetVersion } from '../../dataset/domain/models/Dataset'
 import { FileCriteria } from '../../files/domain/models/FileCriteria'
+import { FilePaginationInfo } from '../../files/domain/models/FilePaginationInfo'
 import { FileMother } from '../../../tests/component/files/domain/models/FileMother'
 
 export class FileMockRepository implements FileRepository {
diff --git a/src/stories/hello-dataverse/HelloDataverse.stories.tsx b/src/stories/hello-dataverse/HelloDataverse.stories.tsx
deleted file mode 100644
index f95572055..000000000
--- a/src/stories/hello-dataverse/HelloDataverse.stories.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react'
-import { HelloDataverse } from '../../sections/hello-dataverse/HelloDataverse'
-import { WithI18next } from '../WithI18next'
-import { WithLayout } from '../WithLayout'
-
-const meta: Meta<typeof HelloDataverse> = {
-  title: 'Pages/Hello Dataverse',
-  component: HelloDataverse,
-  decorators: [WithI18next, WithLayout]
-}
-
-export default meta
-type Story = StoryObj<typeof HelloDataverse>
-
-export const Default: Story = {
-  render: () => <HelloDataverse />
-}
diff --git a/src/stories/home/Home.stories.tsx b/src/stories/home/Home.stories.tsx
new file mode 100644
index 000000000..800bb977e
--- /dev/null
+++ b/src/stories/home/Home.stories.tsx
@@ -0,0 +1,28 @@
+import type { Meta, StoryObj } from '@storybook/react'
+import { Home } from '../../sections/home/Home'
+import { WithI18next } from '../WithI18next'
+import { WithLayout } from '../WithLayout'
+import { DatasetMockRepository } from '../dataset/DatasetMockRepository'
+import { DatasetLoadingMockRepository } from '../dataset/DatasetLoadingMockRepository'
+import { NoDatasetsMockRepository } from '../dataset/NoDatasetsMockRepository'
+
+const meta: Meta<typeof Home> = {
+  title: 'Pages/Home',
+  component: Home,
+  decorators: [WithI18next, WithLayout]
+}
+
+export default meta
+type Story = StoryObj<typeof Home>
+
+export const Default: Story = {
+  render: () => <Home datasetRepository={new DatasetMockRepository()} />
+}
+
+export const Loading: Story = {
+  render: () => <Home datasetRepository={new DatasetLoadingMockRepository()} />
+}
+
+export const NoResults: Story = {
+  render: () => <Home datasetRepository={new NoDatasetsMockRepository()} />
+}
diff --git a/src/stories/home/datasets-list/DatasetCard.stories.tsx b/src/stories/home/datasets-list/DatasetCard.stories.tsx
new file mode 100644
index 000000000..26f6af0da
--- /dev/null
+++ b/src/stories/home/datasets-list/DatasetCard.stories.tsx
@@ -0,0 +1,21 @@
+import { Meta, StoryObj } from '@storybook/react'
+import { WithI18next } from '../../WithI18next'
+import { DatasetCard } from '../../../sections/home/datasets-list/dataset-card/DatasetCard'
+import { DatasetPreviewMother } from '../../../../tests/component/dataset/domain/models/DatasetPreviewMother'
+
+const meta: Meta<typeof DatasetCard> = {
+  title: 'Sections/Home/DatasetCard',
+  component: DatasetCard,
+  decorators: [WithI18next]
+}
+
+export default meta
+type Story = StoryObj<typeof DatasetCard>
+
+export const Default: Story = {
+  render: () => <DatasetCard dataset={DatasetPreviewMother.createDraft()} />
+}
+
+export const Deaccessioned: Story = {
+  render: () => <DatasetCard dataset={DatasetPreviewMother.createDeaccessioned()} />
+}
diff --git a/src/stories/home/datasets-list/DatasetsList.stories.tsx b/src/stories/home/datasets-list/DatasetsList.stories.tsx
new file mode 100644
index 000000000..51287336f
--- /dev/null
+++ b/src/stories/home/datasets-list/DatasetsList.stories.tsx
@@ -0,0 +1,27 @@
+import { Meta, StoryObj } from '@storybook/react'
+import { WithI18next } from '../../WithI18next'
+import { DatasetMockRepository } from '../../dataset/DatasetMockRepository'
+import { DatasetsList } from '../../../sections/home/datasets-list/DatasetsList'
+import { DatasetLoadingMockRepository } from '../../dataset/DatasetLoadingMockRepository'
+import { NoDatasetsMockRepository } from '../../dataset/NoDatasetsMockRepository'
+
+const meta: Meta<typeof DatasetsList> = {
+  title: 'Sections/Home/DatasetsList',
+  component: DatasetsList,
+  decorators: [WithI18next]
+}
+
+export default meta
+type Story = StoryObj<typeof DatasetsList>
+
+export const Default: Story = {
+  render: () => <DatasetsList datasetRepository={new DatasetMockRepository()} />
+}
+
+export const Loading: Story = {
+  render: () => <DatasetsList datasetRepository={new DatasetLoadingMockRepository()} />
+}
+
+export const NoResults: Story = {
+  render: () => <DatasetsList datasetRepository={new NoDatasetsMockRepository()} />
+}
diff --git a/src/stories/home/datasets-list/NoDatasetsMessage.stories.tsx b/src/stories/home/datasets-list/NoDatasetsMessage.stories.tsx
new file mode 100644
index 000000000..d81a48e90
--- /dev/null
+++ b/src/stories/home/datasets-list/NoDatasetsMessage.stories.tsx
@@ -0,0 +1,23 @@
+import { Meta, StoryObj } from '@storybook/react'
+import { Home } from '../../../sections/home/Home'
+import { WithI18next } from '../../WithI18next'
+import { NoDatasetsMessage } from '../../../sections/home/datasets-list/NoDatasetsMessage'
+import { WithLoggedInUser } from '../../WithLoggedInUser'
+
+const meta: Meta<typeof Home> = {
+  title: 'Sections/Home/NoDatasetsMessage',
+  component: Home,
+  decorators: [WithI18next]
+}
+
+export default meta
+type Story = StoryObj<typeof Home>
+
+export const AnonymousUser: Story = {
+  render: () => <NoDatasetsMessage />
+}
+
+export const AuthenticatedUser: Story = {
+  decorators: [WithLoggedInUser],
+  render: () => <NoDatasetsMessage />
+}
diff --git a/src/stories/shared/pagination/PaginationControls.stories.tsx b/src/stories/shared/pagination/PaginationControls.stories.tsx
new file mode 100644
index 000000000..a482f80d2
--- /dev/null
+++ b/src/stories/shared/pagination/PaginationControls.stories.tsx
@@ -0,0 +1,38 @@
+import { Meta, StoryObj } from '@storybook/react'
+import { WithI18next } from '../../WithI18next'
+import { PaginationControls } from '../../../sections/shared/pagination/PaginationControls'
+import { PaginationInfo } from '../../../shared/domain/models/PaginationInfo'
+import { DatasetPaginationInfo } from '../../../dataset/domain/models/DatasetPaginationInfo'
+import { FilePaginationInfo } from '../../../files/domain/models/FilePaginationInfo'
+
+const meta: Meta<typeof PaginationControls> = {
+  title: 'Sections/Shared/Pagination/PaginationControls',
+  component: PaginationControls,
+  decorators: [WithI18next]
+}
+
+export default meta
+type Story = StoryObj<typeof PaginationControls>
+
+const emptyFunction = () => {}
+export const Default: Story = {
+  render: () => (
+    <PaginationControls
+      initialPaginationInfo={
+        new PaginationInfo<DatasetPaginationInfo | FilePaginationInfo>(10, 10, 200)
+      }
+      onPaginationInfoChange={emptyFunction}
+    />
+  )
+}
+
+export const NoEllipsis: Story = {
+  render: () => (
+    <PaginationControls
+      initialPaginationInfo={
+        new PaginationInfo<DatasetPaginationInfo | FilePaginationInfo>(1, 10, 100)
+      }
+      onPaginationInfoChange={emptyFunction}
+    />
+  )
+}
diff --git a/tests/component/dataset/domain/models/DatasetMother.ts b/tests/component/dataset/domain/models/DatasetMother.ts
index 635785501..e20b2c496 100644
--- a/tests/component/dataset/domain/models/DatasetMother.ts
+++ b/tests/component/dataset/domain/models/DatasetMother.ts
@@ -2,6 +2,7 @@ import { faker } from '@faker-js/faker'
 import {
   ANONYMIZED_FIELD_VALUE,
   Dataset,
+  DatasetLabel,
   DatasetDownloadUrls,
   DatasetLabelSemanticMeaning,
   DatasetLabelValue,
@@ -195,6 +196,45 @@ export class DatasetLockMother {
   }
 }
 
+export class DatasetLabelsMother {
+  static create(): DatasetLabel[] {
+    return [{ value: 'Version 1.0', semanticMeaning: DatasetLabelSemanticMeaning.FILE }]
+  }
+
+  static createDraft(): DatasetLabel[] {
+    return [
+      {
+        value: DatasetLabelValue.UNPUBLISHED,
+        semanticMeaning: DatasetLabelSemanticMeaning.WARNING
+      },
+      { value: DatasetLabelValue.DRAFT, semanticMeaning: DatasetLabelSemanticMeaning.DATASET }
+    ]
+  }
+
+  static createDeaccessioned(): DatasetLabel[] {
+    return [
+      {
+        value: DatasetLabelValue.DEACCESSIONED,
+        semanticMeaning: DatasetLabelSemanticMeaning.DANGER
+      }
+    ]
+  }
+}
+
+export class DatasetCitationMother {
+  static create(): string {
+    return 'Finch, Fiona, 2023, "Darwin\'s Finches", <a href="https://doi.org/10.5072/FK2/0YFWKL" target="_blank">https://doi.org/10.5072/FK2/0YFWKL</a>, Root, V1'
+  }
+
+  static createDraft(): string {
+    return 'Finch, Fiona, 2023, "Darwin\'s Finches", <a href="https://doi.org/10.5072/FK2/0YFWKL" target="_blank">https://doi.org/10.5072/FK2/0YFWKL</a>, Root, DRAFT VERSION'
+  }
+
+  static createDeaccessioned(): string {
+    return 'Finch, Fiona, 2023, "Darwin\'s Finches", <a href="https://doi.org/10.5072/FK2/0YFWKL" target="_blank">https://doi.org/10.5072/FK2/0YFWKL</a>, Root, V1, DEACCESSIONED VERSION'
+  }
+}
+
 export class DatasetFileDownloadSizeMother {
   static create(props?: Partial<FileDownloadSize>): FileDownloadSize {
     return new FileDownloadSize(
@@ -235,6 +275,10 @@ export class DatasetMother {
     return undefined
   }
 
+  static createMany(count: number): Dataset[] {
+    return Array.from({ length: count }, () => this.create())
+  }
+
   static create(props?: Partial<Dataset>): Dataset {
     const dataset = {
       persistentId: faker.datatype.uuid(),
@@ -247,24 +291,7 @@ export class DatasetMother {
         uri: 'https://creativecommons.org/publicdomain/zero/1.0/',
         iconUri: 'https://licensebuttons.net/p/zero/1.0/88x31.png'
       },
-      labels: [
-        {
-          value: DatasetLabelValue.IN_REVIEW,
-          semanticMeaning: faker.helpers.arrayElement(Object.values(DatasetLabelSemanticMeaning))
-        },
-        {
-          value: DatasetLabelValue.EMBARGOED,
-          semanticMeaning: faker.helpers.arrayElement(Object.values(DatasetLabelSemanticMeaning))
-        },
-        {
-          value: DatasetLabelValue.UNPUBLISHED,
-          semanticMeaning: faker.helpers.arrayElement(Object.values(DatasetLabelSemanticMeaning))
-        },
-        {
-          value: `Version ${faker.lorem.word()}`,
-          semanticMeaning: faker.helpers.arrayElement(Object.values(DatasetLabelSemanticMeaning))
-        }
-      ],
+      labels: DatasetLabelsMother.create(),
       summaryFields: [
         {
           name: MetadataBlockName.CITATION,
diff --git a/tests/component/dataset/domain/models/DatasetPreviewMother.ts b/tests/component/dataset/domain/models/DatasetPreviewMother.ts
new file mode 100644
index 000000000..83e080ff9
--- /dev/null
+++ b/tests/component/dataset/domain/models/DatasetPreviewMother.ts
@@ -0,0 +1,68 @@
+import { faker } from '@faker-js/faker'
+import { DatasetPreview } from '../../../../../src/dataset/domain/models/DatasetPreview'
+import { DatasetCitationMother, DatasetLabelsMother, DatasetVersionMother } from './DatasetMother'
+
+export class DatasetPreviewMother {
+  static createMany(count: number): DatasetPreview[] {
+    return Array.from({ length: count }, () => this.create())
+  }
+
+  static createManyRealistic(count: number): DatasetPreview[] {
+    return Array.from({ length: count }, () => this.createRealistic())
+  }
+
+  static create(props?: Partial<DatasetPreview>): DatasetPreview {
+    const datasetPreview = {
+      persistentId: faker.datatype.uuid(),
+      title: faker.lorem.sentence(),
+      labels: DatasetLabelsMother.create(),
+      isDeaccessioned: faker.datatype.boolean(),
+      thumbnail: faker.datatype.boolean() ? faker.image.imageUrl() : undefined,
+      releaseOrCreateDate: faker.date.past(),
+      version: DatasetVersionMother.create(),
+      citation: DatasetCitationMother.create(),
+      description: faker.lorem.paragraph(),
+      ...props
+    }
+
+    return new DatasetPreview(
+      datasetPreview.persistentId,
+      datasetPreview.title,
+      datasetPreview.version,
+      datasetPreview.citation,
+      datasetPreview.labels,
+      datasetPreview.isDeaccessioned,
+      datasetPreview.releaseOrCreateDate,
+      datasetPreview.description,
+      datasetPreview.thumbnail
+    )
+  }
+
+  static createRealistic(): DatasetPreview {
+    return faker.datatype.boolean() ? this.createDraft() : this.createDeaccessioned()
+  }
+
+  static createDraft(): DatasetPreview {
+    return this.create({
+      isDeaccessioned: false,
+      labels: DatasetLabelsMother.createDraft(),
+      citation: DatasetCitationMother.createDraft()
+    })
+  }
+
+  static createWithThumbnail(): DatasetPreview {
+    return this.create({ thumbnail: faker.image.imageUrl(), isDeaccessioned: false })
+  }
+
+  static createWithNoThumbnail(): DatasetPreview {
+    return this.create({ thumbnail: undefined, isDeaccessioned: false })
+  }
+
+  static createDeaccessioned(): DatasetPreview {
+    return this.create({
+      isDeaccessioned: true,
+      labels: DatasetLabelsMother.createDeaccessioned(),
+      citation: DatasetCitationMother.createDeaccessioned()
+    })
+  }
+}
diff --git a/tests/component/sections/dataset/Dataset.spec.tsx b/tests/component/sections/dataset/Dataset.spec.tsx
index 70b899057..783479fed 100644
--- a/tests/component/sections/dataset/Dataset.spec.tsx
+++ b/tests/component/sections/dataset/Dataset.spec.tsx
@@ -41,7 +41,7 @@ describe('Dataset', () => {
     mountWithDataset(<Dataset fileRepository={fileRepository} />, testDataset)
 
     cy.findByTestId('dataset-skeleton').should('exist')
-    cy.findByText(testDataset.getTitle()).should('not.exist')
+    cy.findByText(testDataset.title).should('not.exist')
   })
 
   it('renders page not found when dataset is null', () => {
@@ -57,7 +57,7 @@ describe('Dataset', () => {
 
     mountWithDataset(<Dataset fileRepository={fileRepository} />, testDataset)
 
-    cy.findAllByText(testDataset.getTitle()).should('exist')
+    cy.findAllByText(testDataset.title).should('exist')
 
     testDataset.labels.forEach((label) => {
       cy.findAllByText(label.value).should('exist')
@@ -69,7 +69,7 @@ describe('Dataset', () => {
 
     mountWithDataset(<Dataset fileRepository={fileRepository} />, testDataset)
 
-    cy.findAllByText(testDataset.getTitle()).should('exist')
+    cy.findAllByText(testDataset.title).should('exist')
 
     const metadataTab = cy.findByRole('tab', { name: 'Metadata' })
     metadataTab.should('exist')
diff --git a/tests/component/sections/dataset/DatasetProvider.spec.tsx b/tests/component/sections/dataset/DatasetProvider.spec.tsx
index 03684cf44..e396bba45 100644
--- a/tests/component/sections/dataset/DatasetProvider.spec.tsx
+++ b/tests/component/sections/dataset/DatasetProvider.spec.tsx
@@ -9,7 +9,7 @@ function TestComponent() {
 
   return (
     <div>
-      {dataset ? <span>{dataset.getTitle()}</span> : <span>Dataset Not Found</span>}
+      {dataset ? <span>{dataset.title}</span> : <span>Dataset Not Found</span>}
       {isLoading && <div>Loading...</div>}
     </div>
   )
@@ -39,7 +39,7 @@ describe('DatasetProvider', () => {
 
     cy.findByText('Loading...').should('exist')
     cy.wrap(datasetRepository.getByPersistentId).should('be.calledOnceWith', dataset.persistentId)
-    cy.findByText(dataset.getTitle()).should('exist')
+    cy.findByText(dataset.title).should('exist')
     cy.findByText('Loading...').should('not.exist')
   })
 
@@ -60,7 +60,7 @@ describe('DatasetProvider', () => {
       dataset.persistentId,
       'draft'
     )
-    cy.findByText(dataset.getTitle()).should('exist')
+    cy.findByText(dataset.title).should('exist')
     cy.findByText('Loading...').should('not.exist')
   })
 
@@ -80,7 +80,7 @@ describe('DatasetProvider', () => {
       'be.calledOnce',
       'some-private-url-token'
     )
-    cy.findByText(dataset.getTitle()).should('exist')
+    cy.findByText(dataset.title).should('exist')
     cy.findByText('Loading...').should('not.exist')
   })
 
diff --git a/tests/component/sections/dataset/dataset-citation/CitationThumbnail.spec.tsx b/tests/component/sections/dataset/dataset-citation/CitationThumbnail.spec.tsx
deleted file mode 100644
index c73ab2359..000000000
--- a/tests/component/sections/dataset/dataset-citation/CitationThumbnail.spec.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { DatasetPublishingStatus } from '../../../../../src/dataset/domain/models/Dataset'
-import { CitationThumbnail } from '../../../../../src/sections/dataset/dataset-citation/CitationThumbnail'
-
-describe('CitationThumbnail', () => {
-  it('renders the dataset icon when there is no thumbnail', () => {
-    cy.customMount(
-      <CitationThumbnail
-        title="Dataset title"
-        publishingStatus={DatasetPublishingStatus.RELEASED}
-      />
-    )
-
-    cy.findByLabelText('icon-dataset').should('exist')
-  })
-
-  it('renders the dataset icon when the dataset is deaccessioned', () => {
-    cy.customMount(
-      <CitationThumbnail
-        title="Dataset title"
-        thumbnail="https://example.com/image.png"
-        publishingStatus={DatasetPublishingStatus.DEACCESSIONED}
-      />
-    )
-
-    cy.findByLabelText('icon-dataset').should('exist')
-  })
-
-  it('renders the dataset thumbnail when there is one and the dataset is not deaccessioned', () => {
-    cy.customMount(
-      <CitationThumbnail
-        thumbnail="https://example.com/image.png"
-        title="Dataset title"
-        publishingStatus={DatasetPublishingStatus.RELEASED}
-      />
-    )
-
-    cy.findByRole('img', { name: 'Dataset title' }).should('exist')
-  })
-})
diff --git a/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx b/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx
index 77c287336..58a6ec23d 100644
--- a/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx
+++ b/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx
@@ -8,7 +8,6 @@ import {
   FileTag
 } from '../../../../../src/files/domain/models/FileCriteria'
 import { FilesCountInfoMother } from '../../../files/domain/models/FilesCountInfoMother'
-import { FilePaginationInfo } from '../../../../../src/files/domain/models/FilePaginationInfo'
 import { FileSize, FileSizeUnit, FileType } from '../../../../../src/files/domain/models/File'
 import styles from '../../../../../src/sections/dataset/dataset-files/files-table/FilesTable.module.scss'
 import { DatasetMother } from '../../../dataset/domain/models/DatasetMother'
@@ -16,6 +15,7 @@ import { SettingMother } from '../../../settings/domain/models/SettingMother'
 import { ZipDownloadLimit } from '../../../../../src/settings/domain/models/ZipDownloadLimit'
 import { SettingsProvider } from '../../../../../src/sections/settings/SettingsProvider'
 import { SettingRepository } from '../../../../../src/settings/domain/repositories/SettingRepository'
+import { FilePaginationInfo } from '../../../../../src/files/domain/models/FilePaginationInfo'
 
 const testFiles = FileMother.createMany(10)
 const datasetPersistentId = 'test-dataset-persistent-id'
@@ -42,7 +42,7 @@ const testFilesCountInfo = FilesCountInfoMother.create({
     { tag: new FileTag('code'), count: 10 }
   ]
 })
-const filePaginationInfo = new FilePaginationInfo(1, 10, 200)
+const paginationInfo: FilePaginationInfo = new FilePaginationInfo(1, 10, 200)
 const settingsRepository = {} as SettingRepository
 describe('DatasetFiles', () => {
   beforeEach(() => {
@@ -417,7 +417,7 @@ describe('DatasetFiles', () => {
         'be.calledWith',
         datasetPersistentId,
         datasetVersion,
-        filePaginationInfo,
+        paginationInfo,
         new FileCriteria().withSortBy(FileSortByOption.NAME_AZ)
       )
     })
@@ -437,7 +437,7 @@ describe('DatasetFiles', () => {
         'be.calledWith',
         datasetPersistentId,
         datasetVersion,
-        filePaginationInfo,
+        paginationInfo,
         new FileCriteria().withFilterByType('image/png')
       )
     })
@@ -457,7 +457,7 @@ describe('DatasetFiles', () => {
         'be.calledWith',
         datasetPersistentId,
         datasetVersion,
-        filePaginationInfo,
+        paginationInfo,
         new FileCriteria().withFilterByAccess(FileAccessOption.PUBLIC)
       )
     })
@@ -477,7 +477,7 @@ describe('DatasetFiles', () => {
         'be.calledWith',
         datasetPersistentId,
         datasetVersion,
-        filePaginationInfo,
+        paginationInfo,
         new FileCriteria().withFilterByTag('document')
       )
     })
@@ -496,7 +496,7 @@ describe('DatasetFiles', () => {
         'be.calledWith',
         datasetPersistentId,
         datasetVersion,
-        filePaginationInfo,
+        paginationInfo,
         new FileCriteria().withSearchText('test')
       )
     })
diff --git a/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx
index b56ea78d6..cc0d50c3a 100644
--- a/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx
+++ b/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx
@@ -8,8 +8,8 @@ import { SettingMother } from '../../../../settings/domain/models/SettingMother'
 import { ZipDownloadLimit } from '../../../../../../src/settings/domain/models/ZipDownloadLimit'
 import { SettingsContext } from '../../../../../../src/sections/settings/SettingsContext'
 import styles from '../../../../../../src/sections/dataset/dataset-files/files-table/FilesTable.module.scss'
-import { FilePaginationInfo } from '../../../../../../src/files/domain/models/FilePaginationInfo'
 import { FileCriteria } from '../../../../../../src/files/domain/models/FileCriteria'
+import { FilePaginationInfo } from '../../../../../../src/files/domain/models/FilePaginationInfo'
 
 const testFiles = FileMother.createMany(10)
 const paginationInfo = new FilePaginationInfo(1, 10, 200)
diff --git a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDate.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDate.spec.tsx
index 851029fa5..9f605cc54 100644
--- a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDate.spec.tsx
+++ b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDate.spec.tsx
@@ -1,16 +1,13 @@
 import { FileDate } from '../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate'
 import { FileDateType } from '../../../../../../../../../src/files/domain/models/File'
+import { DateHelper } from '../../../../../../../../../src/shared/domain/helpers/DateHelper'
 
 describe('FileDate', () => {
   it('renders the date', () => {
     const fileDate = new Date('2023-09-18')
     const date = { type: FileDateType.PUBLISHED, date: fileDate }
     cy.customMount(<FileDate date={date} />)
-    const dateString = fileDate.toLocaleDateString(Intl.DateTimeFormat().resolvedOptions().locale, {
-      year: 'numeric',
-      month: 'short',
-      day: 'numeric'
-    })
+    const dateString = DateHelper.toDisplayFormat(fileDate)
     cy.findByText(`Published ` + dateString).should('exist')
   })
 })
diff --git a/tests/component/sections/dataset/dataset-files/useFiles.spec.tsx b/tests/component/sections/dataset/dataset-files/useFiles.spec.tsx
index 9f9d9a5d0..6e958064e 100644
--- a/tests/component/sections/dataset/dataset-files/useFiles.spec.tsx
+++ b/tests/component/sections/dataset/dataset-files/useFiles.spec.tsx
@@ -5,12 +5,12 @@ import { useFiles } from '../../../../../src/sections/dataset/dataset-files/useF
 import { FileUserPermissionsMother } from '../../../files/domain/models/FileUserPermissionsMother'
 import { FilePermissionsProvider } from '../../../../../src/sections/file/file-permissions/FilePermissionsProvider'
 import { useState } from 'react'
-import { FilePaginationInfo } from '../../../../../src/files/domain/models/FilePaginationInfo'
 import {
   DatasetPublishingStatus,
   DatasetVersion
 } from '../../../../../src/dataset/domain/models/Dataset'
 import { FileCriteria, FileSortByOption } from '../../../../../src/files/domain/models/FileCriteria'
+import { FilePaginationInfo } from '../../../../../src/files/domain/models/FilePaginationInfo'
 
 const files = FileMother.createMany(100)
 const filesCountInfo = FilesCountInfoMother.create({ total: 100 })
@@ -48,7 +48,7 @@ const FilesTableTestComponent = ({ datasetPersistentId }: { datasetPersistentId:
         }}>
         Sort by name Z-A
       </button>
-      <div>Files count: {paginationInfo.totalFiles}</div>
+      <div>Files count: {paginationInfo.totalItems}</div>
       <div>Files total download size: {filesTotalDownloadSize}</div>
       <table>
         <tbody>
diff --git a/tests/component/sections/dataset/dataset-icon/DatasetIcon.spec.tsx b/tests/component/sections/dataset/dataset-icon/DatasetIcon.spec.tsx
new file mode 100644
index 000000000..163759a50
--- /dev/null
+++ b/tests/component/sections/dataset/dataset-icon/DatasetIcon.spec.tsx
@@ -0,0 +1,9 @@
+import { DatasetIcon } from '../../../../../src/sections/dataset/dataset-icon/DatasetIcon'
+
+describe('DatasetIcon', () => {
+  it('renders the dataset icon', () => {
+    cy.customMount(<DatasetIcon />)
+
+    cy.findByLabelText('icon-dataset').should('exist')
+  })
+})
diff --git a/tests/component/sections/dataset/dataset-thumbanil/DatasetThumbnail.spec.tsx b/tests/component/sections/dataset/dataset-thumbanil/DatasetThumbnail.spec.tsx
new file mode 100644
index 000000000..1bb47523e
--- /dev/null
+++ b/tests/component/sections/dataset/dataset-thumbanil/DatasetThumbnail.spec.tsx
@@ -0,0 +1,29 @@
+import { DatasetThumbnail } from '../../../../../src/sections/dataset/dataset-thumbnail/DatasetThumbnail'
+
+describe('DatasetThumbnail', () => {
+  it('renders the dataset icon when there is no thumbnail', () => {
+    cy.customMount(<DatasetThumbnail title="Dataset title" />)
+
+    cy.findByLabelText('icon-dataset').should('exist')
+  })
+
+  it('renders the dataset icon when the dataset is deaccessioned', () => {
+    cy.customMount(
+      <DatasetThumbnail
+        title="Dataset title"
+        thumbnail="https://example.com/image.png"
+        isDeaccessioned
+      />
+    )
+
+    cy.findByLabelText('icon-dataset').should('exist')
+  })
+
+  it('renders the dataset thumbnail when there is one and the dataset is not deaccessioned', () => {
+    cy.customMount(
+      <DatasetThumbnail thumbnail="https://example.com/image.png" title="Dataset title" />
+    )
+
+    cy.findByRole('img', { name: 'Dataset title' }).should('exist')
+  })
+})
diff --git a/tests/component/sections/hello-dataverse/HelloDataverse.spec.tsx b/tests/component/sections/hello-dataverse/HelloDataverse.spec.tsx
deleted file mode 100644
index 7e1668691..000000000
--- a/tests/component/sections/hello-dataverse/HelloDataverse.spec.tsx
+++ /dev/null
@@ -1,8 +0,0 @@
-import { HelloDataverse } from '../../../../src/sections/hello-dataverse/HelloDataverse'
-
-describe('HelloDataverse page', () => {
-  it('renders hello dataverse title', () => {
-    cy.customMount(<HelloDataverse />)
-    cy.findByRole('heading').should('contain.text', 'Hello Dataverse')
-  })
-})
diff --git a/tests/component/sections/home/Home.spec.tsx b/tests/component/sections/home/Home.spec.tsx
new file mode 100644
index 000000000..52fe1d34a
--- /dev/null
+++ b/tests/component/sections/home/Home.spec.tsx
@@ -0,0 +1,28 @@
+import { Home } from '../../../../src/sections/home/Home'
+import { DatasetRepository } from '../../../../src/dataset/domain/repositories/DatasetRepository'
+import { DatasetPreviewMother } from '../../dataset/domain/models/DatasetPreviewMother'
+
+const datasetRepository: DatasetRepository = {} as DatasetRepository
+const totalDatasetsCount = 10
+const datasets = DatasetPreviewMother.createMany(totalDatasetsCount)
+describe('Home page', () => {
+  beforeEach(() => {
+    datasetRepository.getAll = cy.stub().resolves(datasets)
+    datasetRepository.getTotalDatasetsCount = cy.stub().resolves(totalDatasetsCount)
+  })
+
+  it('renders Root title', () => {
+    cy.customMount(<Home datasetRepository={datasetRepository} />)
+    cy.findByRole('heading').should('contain.text', 'Root')
+  })
+
+  it('renders the datasets list', () => {
+    cy.customMount(<Home datasetRepository={datasetRepository} />)
+
+    cy.wrap(datasetRepository.getAll).should('be.calledOnce')
+
+    datasets.forEach((dataset) => {
+      cy.findByText(dataset.title).should('exist')
+    })
+  })
+})
diff --git a/tests/component/sections/home/datasets-list/DatasetsList.spec.tsx b/tests/component/sections/home/datasets-list/DatasetsList.spec.tsx
new file mode 100644
index 000000000..e126ce245
--- /dev/null
+++ b/tests/component/sections/home/datasets-list/DatasetsList.spec.tsx
@@ -0,0 +1,58 @@
+import { DatasetRepository } from '../../../../../src/dataset/domain/repositories/DatasetRepository'
+import { DatasetsList } from '../../../../../src/sections/home/datasets-list/DatasetsList'
+import { DatasetPaginationInfo } from '../../../../../src/dataset/domain/models/DatasetPaginationInfo'
+import { DatasetPreviewMother } from '../../../dataset/domain/models/DatasetPreviewMother'
+
+const datasetRepository: DatasetRepository = {} as DatasetRepository
+const totalDatasetsCount = 200
+const datasets = DatasetPreviewMother.createMany(totalDatasetsCount)
+describe('Datasets List', () => {
+  beforeEach(() => {
+    datasetRepository.getAll = cy.stub().resolves(datasets)
+    datasetRepository.getTotalDatasetsCount = cy.stub().resolves(totalDatasetsCount)
+  })
+
+  it('renders skeleton while loading', () => {
+    cy.customMount(<DatasetsList datasetRepository={datasetRepository} />)
+
+    cy.findByTestId('datasets-list-skeleton').should('exist')
+    datasets.forEach((dataset) => {
+      cy.findByRole('link', { name: dataset.title }).should('not.exist')
+    })
+  })
+
+  it('renders no datasets message when there are no datasets', () => {
+    datasetRepository.getAll = cy.stub().resolves([])
+    cy.customMount(<DatasetsList datasetRepository={datasetRepository} />)
+
+    cy.findByText(/This dataverse currently has no datasets./).should('exist')
+  })
+
+  it('renders the datasets list', () => {
+    cy.customMount(<DatasetsList datasetRepository={datasetRepository} />)
+
+    cy.wrap(datasetRepository.getAll).should(
+      'be.calledOnceWith',
+      new DatasetPaginationInfo(1, 10, totalDatasetsCount)
+    )
+
+    cy.findByText('1 to 10 of 200 Datasets').should('exist')
+    datasets.forEach((dataset) => {
+      cy.findByText(dataset.title)
+        .should('exist')
+        .should('have.attr', 'href', `/datasets?persistentId=${dataset.persistentId}`)
+    })
+  })
+
+  it('renders the datasets list with the correct header on a page different than the first one ', () => {
+    cy.customMount(<DatasetsList datasetRepository={datasetRepository} />)
+
+    cy.findByRole('button', { name: '6' }).click()
+
+    cy.wrap(datasetRepository.getAll).should(
+      'be.calledWith',
+      new DatasetPaginationInfo(1, 10, totalDatasetsCount).goToPage(6)
+    )
+    cy.findByText('51 to 60 of 200 Datasets').should('exist')
+  })
+})
diff --git a/tests/component/sections/home/datasets-list/NoDatasetsMessage.spec.tsx b/tests/component/sections/home/datasets-list/NoDatasetsMessage.spec.tsx
new file mode 100644
index 000000000..c8b580bea
--- /dev/null
+++ b/tests/component/sections/home/datasets-list/NoDatasetsMessage.spec.tsx
@@ -0,0 +1,20 @@
+import { NoDatasetsMessage } from '../../../../../src/sections/home/datasets-list/NoDatasetsMessage'
+
+describe('No Datasets Message', () => {
+  it('renders the message for anonymous user', () => {
+    cy.customMount(<NoDatasetsMessage />)
+    cy.findByText(/This dataverse currently has no datasets. Please /).should('exist')
+    cy.findByRole('link', { name: 'log in' }).should(
+      'have.attr',
+      'href',
+      '/loginpage.xhtml?redirectPage=%2Fdataverse.xhtml'
+    )
+  })
+
+  it('renders the message for authenticated user', () => {
+    cy.mountAuthenticated(<NoDatasetsMessage />)
+    cy.findByText(
+      'This dataverse currently has no datasets. You can add to it by using the Add Data button on this page.'
+    ).should('exist')
+  })
+})
diff --git a/tests/component/sections/home/datasets-list/dataset-card/DatasetCard.spec.tsx b/tests/component/sections/home/datasets-list/dataset-card/DatasetCard.spec.tsx
new file mode 100644
index 000000000..8b66c37d1
--- /dev/null
+++ b/tests/component/sections/home/datasets-list/dataset-card/DatasetCard.spec.tsx
@@ -0,0 +1,21 @@
+import { DatasetPreviewMother } from '../../../../dataset/domain/models/DatasetPreviewMother'
+import { DatasetCard } from '../../../../../../src/sections/home/datasets-list/dataset-card/DatasetCard'
+import { DateHelper } from '../../../../../../src/shared/domain/helpers/DateHelper'
+import styles from '../../../../../../src/sections/home/datasets-list/dataset-card/DatasetCard.module.scss'
+
+describe('DatasetCard', () => {
+  it('should render the card', () => {
+    const dataset = DatasetPreviewMother.createWithThumbnail()
+    cy.customMount(<DatasetCard dataset={dataset} />)
+
+    cy.findByText(dataset.title).should('exist')
+
+    cy.findByRole('img', { name: dataset.title }).should('exist')
+    cy.findByText(DateHelper.toDisplayFormat(dataset.releaseOrCreateDate)).should('exist')
+    cy.findByText(/Finch, Fiona, 2023, "Darwin's Finches"/)
+      .should('exist')
+      .parent()
+      .should('have.class', styles['citation-box'])
+    cy.findByText(dataset.abbreviatedDescription).should('exist')
+  })
+})
diff --git a/tests/component/sections/home/datasets-list/dataset-card/DatasetCardHeader.spec.tsx b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardHeader.spec.tsx
new file mode 100644
index 000000000..1e7773dfc
--- /dev/null
+++ b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardHeader.spec.tsx
@@ -0,0 +1,17 @@
+import { DatasetCardHeader } from '../../../../../../src/sections/home/datasets-list/dataset-card/DatasetCardHeader'
+import { DatasetPreviewMother } from '../../../../dataset/domain/models/DatasetPreviewMother'
+
+describe('DatasetCardHeader', () => {
+  it('should render the header', () => {
+    const dataset = DatasetPreviewMother.create()
+    cy.customMount(<DatasetCardHeader dataset={dataset} />)
+
+    cy.findByText(dataset.title)
+      .should('exist')
+      .should('have.attr', 'href', `/datasets?persistentId=${dataset.persistentId}`)
+    dataset.labels.forEach((label) => {
+      cy.findByText(label.value).should('exist')
+    })
+    cy.findByLabelText('icon-dataset').should('exist')
+  })
+})
diff --git a/tests/component/sections/home/datasets-list/dataset-card/DatasetCardInfo.spec.tsx b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardInfo.spec.tsx
new file mode 100644
index 000000000..5563fe412
--- /dev/null
+++ b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardInfo.spec.tsx
@@ -0,0 +1,28 @@
+import { DatasetPreviewMother } from '../../../../dataset/domain/models/DatasetPreviewMother'
+import { DateHelper } from '../../../../../../src/shared/domain/helpers/DateHelper'
+import styles from '../../../../../../src/sections/home/datasets-list/dataset-card/DatasetCard.module.scss'
+import { DatasetCardInfo } from '../../../../../../src/sections/home/datasets-list/dataset-card/DatasetCardInfo'
+
+describe('DatasetCardInfo', () => {
+  it('should render the dataset info', () => {
+    const dataset = DatasetPreviewMother.createDraft()
+    cy.customMount(<DatasetCardInfo dataset={dataset} />)
+
+    cy.findByText(DateHelper.toDisplayFormat(dataset.releaseOrCreateDate)).should('exist')
+    cy.findByText(/Finch, Fiona, 2023, "Darwin's Finches"/)
+      .should('exist')
+      .parent()
+      .should('have.class', styles['citation-box'])
+    cy.findByText(dataset.abbreviatedDescription).should('exist')
+  })
+
+  it('should render the citation with the deaccessioned background if the dataset is deaccessioned', () => {
+    const dataset = DatasetPreviewMother.createDeaccessioned()
+    cy.customMount(<DatasetCardInfo dataset={dataset} />)
+
+    cy.findByText(/Finch, Fiona, 2023, "Darwin's Finches"/)
+      .should('exist')
+      .parent()
+      .should('have.class', styles['citation-box-deaccessioned'])
+  })
+})
diff --git a/tests/component/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.spec.tsx b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.spec.tsx
new file mode 100644
index 000000000..e261e32db
--- /dev/null
+++ b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.spec.tsx
@@ -0,0 +1,25 @@
+import { DatasetPreviewMother } from '../../../../dataset/domain/models/DatasetPreviewMother'
+import { DatasetCardThumbnail } from '../../../../../../src/sections/home/datasets-list/dataset-card/DatasetCardThumbnail'
+
+describe('DatasetCardThumbnail', () => {
+  it('should render the thumbnail', () => {
+    const dataset = DatasetPreviewMother.createWithThumbnail()
+    cy.customMount(<DatasetCardThumbnail dataset={dataset} />)
+
+    cy.findByRole('img', { name: dataset.title })
+      .should('exist')
+      .parent('a')
+      .should('have.attr', 'href', `/datasets?persistentId=${dataset.persistentId}`)
+  })
+
+  it('should render the placeholder if the dataset has no thumbnail', () => {
+    const dataset = DatasetPreviewMother.createWithNoThumbnail()
+    cy.customMount(<DatasetCardThumbnail dataset={dataset} />)
+
+    cy.findByRole('img', { name: 'icon-dataset' })
+      .should('exist')
+      .parent()
+      .parent('a')
+      .should('have.attr', 'href', `/datasets?persistentId=${dataset.persistentId}`)
+  })
+})
diff --git a/tests/component/sections/layout/header/Header.spec.tsx b/tests/component/sections/layout/header/Header.spec.tsx
index a3c208624..9db242389 100644
--- a/tests/component/sections/layout/header/Header.spec.tsx
+++ b/tests/component/sections/layout/header/Header.spec.tsx
@@ -11,6 +11,17 @@ describe('Header component', () => {
     userRepository.removeAuthenticated = cy.stub().resolves()
   })
 
+  it('displays the brand', () => {
+    cy.customMount(
+      <SessionProvider repository={userRepository}>
+        <Header />
+      </SessionProvider>
+    )
+
+    cy.findByRole('link', { name: /Dataverse/ }).should('exist')
+    cy.findByRole('link').should('have.attr', 'href', '/spa/')
+  })
+
   it('displays the user name when the user is logged in', () => {
     cy.customMount(
       <SessionProvider repository={userRepository}>
diff --git a/tests/component/sections/session/useSession.spec.tsx b/tests/component/sections/session/useSession.spec.tsx
index bd5f678b4..a1f15f1d0 100644
--- a/tests/component/sections/session/useSession.spec.tsx
+++ b/tests/component/sections/session/useSession.spec.tsx
@@ -32,11 +32,14 @@ describe('useSession', () => {
   it('should unset user after calling logOut on repository', () => {
     function TestComponent() {
       const { user, logout } = useSession()
+      const onLogoutClick = () => {
+        void logout()
+      }
 
       return (
         <div>
           {user ? <span>{user.name}</span> : <></>}
-          <Button onClick={logout}>Log Out</Button>
+          <Button onClick={onLogoutClick}>Log Out</Button>
         </div>
       )
     }
diff --git a/tests/component/sections/shared/citation/CitationDescription.spec.tsx b/tests/component/sections/shared/citation/CitationDescription.spec.tsx
new file mode 100644
index 000000000..ce5b1a57e
--- /dev/null
+++ b/tests/component/sections/shared/citation/CitationDescription.spec.tsx
@@ -0,0 +1,12 @@
+import { CitationDescription } from '../../../../../src/sections/shared/citation/CitationDescription'
+
+describe('CitationDescription', () => {
+  it('renders the citation', () => {
+    const citation =
+      'Finch, Fiona, 2023, "Darwin\'s Finches", <a href="https://doi.org/10.5072/FK2/0YFWKL" target="_blank">https://doi.org/10.5072/FK2/0YFWKL</a>, Root, V1'
+    cy.customMount(<CitationDescription citation={citation} />)
+
+    cy.findByText(/Finch, Fiona, 2023, "Darwin's Finches",/).should('exist')
+    cy.findByRole('link', { name: 'https://doi.org/10.5072/FK2/0YFWKL' }).should('exist')
+  })
+})
diff --git a/tests/component/sections/shared/link-to-page/LinkToPage.spec.tsx b/tests/component/sections/shared/link-to-page/LinkToPage.spec.tsx
new file mode 100644
index 000000000..25d166231
--- /dev/null
+++ b/tests/component/sections/shared/link-to-page/LinkToPage.spec.tsx
@@ -0,0 +1,14 @@
+import { LinkToPage } from '../../../../../src/sections/shared/link-to-page/LinkToPage'
+import { Route } from '../../../../../src/sections/Route.enum'
+
+describe('LinkToPage', () => {
+  it('renders a link to the page with the given search params', () => {
+    cy.customMount(<LinkToPage page={Route.DATASETS} searchParams={{ foo: 'bar' }} />)
+    cy.findByRole('link').should('have.attr', 'href', '/datasets?foo=bar')
+  })
+
+  it('renders a link to the page without search params', () => {
+    cy.customMount(<LinkToPage page={Route.DATASETS} />)
+    cy.findByRole('link').should('have.attr', 'href', '/datasets')
+  })
+})
diff --git a/tests/component/sections/dataset/dataset-files/files-pagination/PageNumbersButtonsWithEllipsis.spec.tsx b/tests/component/sections/shared/pagination/PageNumbersButtonsWithEllipsis.spec.tsx
similarity index 95%
rename from tests/component/sections/dataset/dataset-files/files-pagination/PageNumbersButtonsWithEllipsis.spec.tsx
rename to tests/component/sections/shared/pagination/PageNumbersButtonsWithEllipsis.spec.tsx
index 0b4fffc39..eb644b64b 100644
--- a/tests/component/sections/dataset/dataset-files/files-pagination/PageNumbersButtonsWithEllipsis.spec.tsx
+++ b/tests/component/sections/shared/pagination/PageNumbersButtonsWithEllipsis.spec.tsx
@@ -1,4 +1,4 @@
-import { PageNumbersButtonsWithEllipsis } from '../../../../../../src/sections/dataset/dataset-files/files-pagination/PageNumbersButtonsWithEllipsis'
+import { PageNumbersButtonsWithEllipsis } from '../../../../../src/sections/shared/pagination/PageNumbersButtonsWithEllipsis'
 
 let goToPage: (pageIndex: number) => void
 const selectedPageIndex = 3
diff --git a/tests/component/sections/dataset/dataset-files/files-pagination/FilesPagination.spec.tsx b/tests/component/sections/shared/pagination/PaginationControls.spec.tsx
similarity index 63%
rename from tests/component/sections/dataset/dataset-files/files-pagination/FilesPagination.spec.tsx
rename to tests/component/sections/shared/pagination/PaginationControls.spec.tsx
index df2a50ce6..4ca16340c 100644
--- a/tests/component/sections/dataset/dataset-files/files-pagination/FilesPagination.spec.tsx
+++ b/tests/component/sections/shared/pagination/PaginationControls.spec.tsx
@@ -1,23 +1,27 @@
-import { FilesPagination } from '../../../../../../src/sections/dataset/dataset-files/files-pagination/FilesPagination'
-import { FilePaginationInfo } from '../../../../../../src/files/domain/models/FilePaginationInfo'
+import { PaginationControls } from '../../../../../src/sections/shared/pagination/PaginationControls'
+import { PaginationInfo } from '../../../../../src/shared/domain/models/PaginationInfo'
+import { FilePaginationInfo } from '../../../../../src/files/domain/models/FilePaginationInfo'
+import { DatasetPaginationInfo } from '../../../../../src/dataset/domain/models/DatasetPaginationInfo'
 
-let paginationInfo: FilePaginationInfo
+let paginationInfo: PaginationInfo<FilePaginationInfo | DatasetPaginationInfo>
 const page = 3
 const pageSize = 10
 const total = 200
-describe('FilesPagination', () => {
+describe('PaginationControls', () => {
   beforeEach(() => {
     cy.viewport(1000, 1000)
-    paginationInfo = new FilePaginationInfo(page, pageSize, total)
+    paginationInfo = new PaginationInfo<FilePaginationInfo | DatasetPaginationInfo>(
+      page,
+      pageSize,
+      total
+    )
   })
 
   it('clicking on the first page button calls goToPage 1', () => {
     const onPaginationInfoChange = cy.stub().as('onPaginationInfoChange')
     cy.customMount(
-      <FilesPagination
-        page={page}
-        pageSize={pageSize}
-        total={total}
+      <PaginationControls
+        initialPaginationInfo={paginationInfo}
         onPaginationInfoChange={onPaginationInfoChange}
       />
     )
@@ -29,10 +33,8 @@ describe('FilesPagination', () => {
   it('clicking on the previous page button calls goToPreviousPage', () => {
     const onPaginationInfoChange = cy.stub().as('onPaginationInfoChange')
     cy.customMount(
-      <FilesPagination
-        page={page}
-        pageSize={pageSize}
-        total={total}
+      <PaginationControls
+        initialPaginationInfo={paginationInfo}
         onPaginationInfoChange={onPaginationInfoChange}
       />
     )
@@ -47,10 +49,8 @@ describe('FilesPagination', () => {
   it('clicking on a page button calls goToPage with the correct number', () => {
     const onPaginationInfoChange = cy.stub().as('onPaginationInfoChange')
     cy.customMount(
-      <FilesPagination
-        page={page}
-        pageSize={pageSize}
-        total={total}
+      <PaginationControls
+        initialPaginationInfo={paginationInfo}
         onPaginationInfoChange={onPaginationInfoChange}
       />
     )
@@ -62,10 +62,8 @@ describe('FilesPagination', () => {
   it('clicking on the next page button calls goToNextPage', () => {
     const onPaginationInfoChange = cy.stub().as('onPaginationInfoChange')
     cy.customMount(
-      <FilesPagination
-        page={page}
-        pageSize={pageSize}
-        total={total}
+      <PaginationControls
+        initialPaginationInfo={paginationInfo}
         onPaginationInfoChange={onPaginationInfoChange}
       />
     )
@@ -77,10 +75,8 @@ describe('FilesPagination', () => {
   it('clicking on the last page button calls setPageIndex with the last index', () => {
     const onPaginationInfoChange = cy.stub().as('onPaginationInfoChange')
     cy.customMount(
-      <FilesPagination
-        page={page}
-        pageSize={pageSize}
-        total={total}
+      <PaginationControls
+        initialPaginationInfo={paginationInfo}
         onPaginationInfoChange={onPaginationInfoChange}
       />
     )
@@ -92,15 +88,13 @@ describe('FilesPagination', () => {
   it('selecting a page size calls setPageSize with the selected value', () => {
     const onPaginationInfoChange = cy.stub().as('onPaginationInfoChange')
     cy.customMount(
-      <FilesPagination
-        page={page}
-        pageSize={pageSize}
-        total={total}
+      <PaginationControls
+        initialPaginationInfo={paginationInfo}
         onPaginationInfoChange={onPaginationInfoChange}
       />
     )
 
-    cy.findByLabelText('Files per page').select('50')
+    cy.findByLabelText('Items per page').select('50')
     cy.wrap(onPaginationInfoChange).should('have.been.calledWith', paginationInfo.withPageSize(50))
 
     cy.findByRole('button', { name: 'Last' }).click()
@@ -109,4 +103,17 @@ describe('FilesPagination', () => {
       paginationInfo.withPageSize(50).goToPage(4)
     )
   })
+
+  it('does not show the page size selector if the prop is false', () => {
+    const onPaginationInfoChange = cy.stub().as('onPaginationInfoChange')
+    cy.customMount(
+      <PaginationControls
+        initialPaginationInfo={paginationInfo.withTotal(10)}
+        onPaginationInfoChange={onPaginationInfoChange}
+        showPageSizeSelector={false}
+      />
+    )
+
+    cy.findByLabelText('Items per page').should('not.exist')
+  })
 })
diff --git a/tests/e2e-integration/e2e/sections/hello-dataverse/HelloDataverse.spec.ts b/tests/e2e-integration/e2e/sections/home/Home.spec.ts
similarity index 59%
rename from tests/e2e-integration/e2e/sections/hello-dataverse/HelloDataverse.spec.ts
rename to tests/e2e-integration/e2e/sections/home/Home.spec.ts
index 4e364a2ea..1f85bc181 100644
--- a/tests/e2e-integration/e2e/sections/hello-dataverse/HelloDataverse.spec.ts
+++ b/tests/e2e-integration/e2e/sections/home/Home.spec.ts
@@ -1,23 +1,23 @@
-describe('Hello Dataverse', () => {
+describe('Home Page', () => {
   it('successfully loads', () => {
     cy.visit('/spa')
-    cy.findAllByText(/Hello Dataverse/i).should('exist')
+    cy.findAllByText(/Root/i).should('exist')
   })
 
   it('log in Dataverse Admin user', () => {
     cy.loginAsAdmin('/spa')
 
-    cy.findAllByText(/Hello Dataverse/i).should('exist')
+    cy.findAllByText(/Root/i).should('exist')
     cy.findByText(/Dataverse Admin/i).should('exist')
   })
 
   it('log out Dataverse Admin user', () => {
     cy.loginAsAdmin('/spa')
 
-    cy.findAllByText(/Hello Dataverse/i).should('exist')
+    cy.findAllByText(/Root/i).should('exist')
 
     cy.findByText(/Dataverse Admin/i).click()
-    cy.findByRole('link', { name: /Log Out/i }).click()
+    cy.findByRole('button', { name: /Log Out/i }).click()
     cy.findByText(/Dataverse Admin/i).should('not.exist')
   })
 })
diff --git a/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts b/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts
index 4916d056b..5d0336a02 100644
--- a/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts
+++ b/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts
@@ -121,7 +121,7 @@ describe('Dataset JSDataverse Repository', () => {
       }
       const datasetExpected = datasetData(dataset.persistentId, dataset.version.id)
 
-      expect(dataset.getTitle()).to.deep.equal(datasetExpected.title)
+      expect(dataset.title).to.deep.equal(datasetExpected.title)
       expect(dataset.citation).to.deep.equal(datasetExpected.citation)
       expect(dataset.labels).to.deep.equal(datasetExpected.labels)
       expect(dataset.license).to.deep.equal(datasetExpected.license)
@@ -162,7 +162,7 @@ describe('Dataset JSDataverse Repository', () => {
           0
         )
         const expectedPublicationDate = getCurrentDateInYYYYMMDDFormat()
-        expect(dataset.getTitle()).to.deep.equal(datasetExpected.title)
+        expect(dataset.title).to.deep.equal(datasetExpected.title)
         expect(dataset.version).to.deep.equal(newVersion)
         expect(dataset.metadataBlocks[0].fields.publicationDate).to.deep.equal(
           expectedPublicationDate
@@ -200,7 +200,7 @@ describe('Dataset JSDataverse Repository', () => {
           0
         )
         const expectedPublicationDate = getCurrentDateInYYYYMMDDFormat()
-        expect(dataset.getTitle()).to.deep.equal(datasetExpected.title)
+        expect(dataset.title).to.deep.equal(datasetExpected.title)
         expect(dataset.version).to.deep.equal(newVersion)
         expect(dataset.metadataBlocks[0].fields.publicationDate).to.deep.equal(
           expectedPublicationDate
@@ -221,7 +221,7 @@ describe('Dataset JSDataverse Repository', () => {
         }
         const datasetExpected = datasetData(dataset.persistentId, dataset.version.id)
 
-        expect(dataset.getTitle()).to.deep.equal(datasetExpected.title)
+        expect(dataset.title).to.deep.equal(datasetExpected.title)
         expect(dataset.version).to.deep.equal(datasetExpected.version)
       })
   })
@@ -236,7 +236,7 @@ describe('Dataset JSDataverse Repository', () => {
       }
       const datasetExpected = datasetData(dataset.persistentId, dataset.version.id)
 
-      expect(dataset.getTitle()).to.deep.equal(datasetExpected.title)
+      expect(dataset.title).to.deep.equal(datasetExpected.title)
       expect(dataset.version).to.deep.equal(datasetExpected.version)
       expect(dataset.permissions).to.deep.equal(datasetExpected.permissions)
     })
@@ -278,7 +278,7 @@ describe('Dataset JSDataverse Repository', () => {
       }
       const datasetExpected = datasetData(dataset.persistentId, dataset.version.id)
 
-      expect(dataset.getTitle()).to.deep.equal(datasetExpected.title)
+      expect(dataset.title).to.deep.equal(datasetExpected.title)
     })
   })
   it('gets the dataset by persistentId when is locked', async () => {
@@ -291,7 +291,7 @@ describe('Dataset JSDataverse Repository', () => {
       }
       const datasetExpected = datasetData(dataset.persistentId, dataset.version.id)
 
-      expect(dataset.getTitle()).to.deep.equal(datasetExpected.title)
+      expect(dataset.title).to.deep.equal(datasetExpected.title)
       expect(dataset.locks).to.deep.equal([
         {
           userPersistentId: 'dataverseAdmin',
diff --git a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts
index df8d92afe..d079f9e2a 100644
--- a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts
+++ b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts
@@ -18,7 +18,6 @@ import {
   DatasetPublishingStatus,
   DatasetVersion
 } from '../../../../src/dataset/domain/models/Dataset'
-import { FilePaginationInfo } from '../../../../src/files/domain/models/FilePaginationInfo'
 import {
   FileAccessOption,
   FileCriteria,
@@ -28,6 +27,7 @@ import {
 import { DatasetHelper } from '../../shared/datasets/DatasetHelper'
 import { FileData, FileHelper } from '../../shared/files/FileHelper'
 import { FilesCountInfo } from '../../../../src/files/domain/models/FilesCountInfo'
+import { FilePaginationInfo } from '../../../../src/files/domain/models/FilePaginationInfo'
 
 chai.use(chaiAsPromised)
 const expect = chai.expect
diff --git a/tests/support/commands.tsx b/tests/support/commands.tsx
index 92229d209..d0f69cdf9 100644
--- a/tests/support/commands.tsx
+++ b/tests/support/commands.tsx
@@ -45,14 +45,17 @@ import { I18nextProvider } from 'react-i18next'
 import i18next from '../../src/i18n'
 import { UserRepository } from '../../src/users/domain/repositories/UserRepository'
 import { SessionProvider } from '../../src/sections/session/SessionProvider'
+import { MemoryRouter } from 'react-router-dom'
 
 // Define your custom mount function
 
 Cypress.Commands.add('customMount', (component: ReactNode) => {
   return cy.mount(
-    <ThemeProvider>
-      <I18nextProvider i18n={i18next}>{component}</I18nextProvider>
-    </ThemeProvider>
+    <MemoryRouter>
+      <ThemeProvider>
+        <I18nextProvider i18n={i18next}>{component}</I18nextProvider>
+      </ThemeProvider>
+    </MemoryRouter>
   )
 })