diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.html b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..bab731906a705e19357f04395d5b488bb2e3c070
--- /dev/null
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.html
@@ -0,0 +1 @@
+<ngx-json-viewer [json]="getValue()"></ngx-json-viewer>
\ No newline at end of file
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.ts b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7a20dfbeebe6a3725aa194acce1904b738c06190
--- /dev/null
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.ts
@@ -0,0 +1,19 @@
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
+
+import { Attribute } from 'src/app/metamodel/models';
+
+@Component({
+    selector: 'app-display-json',
+    templateUrl: 'display-json.component.html',
+    changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class DisplayJsonComponent {
+    @Input() object: any;
+    @Input() attributeList: Attribute[];
+    @Input() attributeJsonId: number;
+
+    getValue() {
+        const labelAttributeJson = this.attributeList.find(attribute => attribute.id === this.attributeJsonId).label;
+        return this.object[labelAttributeJson];
+    }
+}
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.html b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.html
index eed45dc78075ec85cdd626e070aa86687142e76e..62575ebaa797acfba867c0a4e4463509cd106b35 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.html
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.html
@@ -1,6 +1,6 @@
 <!-- Accordion categories -->
 <accordion [isAnimated]="true">
-    <accordion-group [panelClass]="'custom-accordion'" #ag [isOpen]="true" class="my-2">
+    <accordion-group [panelClass]="'custom-accordion'" #ag [isOpen]="isOpened" class="my-2">
         <button class="btn btn-link btn-block clearfix pb-2" accordion-heading>
             <span class="pull-left float-left">
                 {{ getCategory().label }}
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.ts b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.ts
index 015fe691ba98fa0c6de7ba82852eaf51c1ed177f..023a1244d34ef952453e9ac5939b6e95dd895798 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.ts
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.ts
@@ -19,6 +19,7 @@ export class DisplayObjectByOutputCategoryComponent {
     @Input() outputCategoryList: OutputCategory[];
     @Input() queryParams: SearchQueryParams;
     @Input() outputCategoryId: number;
+    @Input() isOpened: boolean;
 
     constructor(protected store: Store<{}>) { }
 
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.html b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.html
index 03c8324e56d54ebc07c1d6e32bf7ce0760b93ba2..965f015a22cf7f9c3c3985a502f48e827ca6447e 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.html
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.html
@@ -1,6 +1,6 @@
 <!-- Accordion families -->
 <accordion [isAnimated]="true">
-    <accordion-group [panelClass]="'custom-accordion'" #ag [isOpen]="true" class="my-2">
+    <accordion-group [panelClass]="'custom-accordion'" #ag [isOpen]="isOpened" class="my-2">
         <button class="btn btn-link btn-block clearfix" accordion-heading>
             <span class="pull-left float-left">
                 {{ getFamily().label }}
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.ts b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.ts
index fda6fb34fb8839a005ab7da584c8dd553a8433af..5b965f864a56cefe45621e22087f350aa002238e 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.ts
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.ts
@@ -20,6 +20,7 @@ export class DisplayObjectByOutputFamilyComponent {
     @Input() outputCategoryList: OutputCategory[];
     @Input() queryParams: SearchQueryParams;
     @Input() outputFamilyId: number;
+    @Input() isOpened: boolean;
 
     constructor(protected store: Store<{}>) { }
 
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.html b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.html
index 035011ce7f1480265a082c3227754ce09bbe4a74..93dcf1467ddcc0dc30bbfdf592ec58d54cf2fc0a 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.html
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.html
@@ -1 +1,14 @@
-{{ object[getAttributeById().label] }}
\ No newline at end of file
+<app-display-detail-renderer
+    *ngIf="rendererEnabled; else displayValue"
+    [rendererType]="'detail'"
+    [value]="object[getAttributeById().label]"
+    [dataset]="dataset"
+    [instance]="instance"
+    [attribute]="getAttributeById()"
+    [queryParams]="queryParams"
+    (downloadFile)="downloadFile($event)">
+</app-display-detail-renderer>
+
+<ng-template #displayValue>
+    {{ object[getAttributeById().label] }}
+</ng-template>
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.ts b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.ts
index ad1dca1c5eefcc8639ab25bb5c181662cea0914c..92772c1ec8ec79089e78934ec04100a470c47f2a 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.ts
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.ts
@@ -1,6 +1,10 @@
 import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
 
-import { Attribute } from 'src/app/metamodel/models';
+import { Store } from '@ngrx/store';
+
+import { Attribute, Dataset, Instance, OutputCategory } from 'src/app/metamodel/models';
+import { SearchQueryParams } from 'src/app/instance/store/models';
+import * as searchActions from 'src/app/instance/store/actions/search.actions';
 
 @Component({
     selector: 'app-display-value-by-attribute',
@@ -9,10 +13,25 @@ import { Attribute } from 'src/app/metamodel/models';
 })
 export class DisplayValueByAttributeComponent {
     @Input() object: any;
+    @Input() dataset: Dataset;
+    @Input() instance: Instance;
     @Input() attributeList: Attribute[];
+    @Input() queryParams: SearchQueryParams;
     @Input() attributeId: number;
+    @Input() rendererEnabled: boolean;
+
+    constructor(protected store: Store<{}>) { }
 
     getAttributeById() {
         return this.attributeList.find(attribute => attribute.id === this.attributeId);
     }
+
+    /**
+     * Dispatches action to launch the file download
+     * 
+     * @param { url: string, filename: string } download
+     */
+    downloadFile(download: { url: string, filename: string }): void {
+        this.store.dispatch(searchActions.downloadFile(download));
+    }
 }
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/index.ts b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/index.ts
index 440ca4677f4b391fb2c61421b5ca81ab7e2127ea..7451ee92016beb0c27b88005fdb86e29b224c228 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/index.ts
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/index.ts
@@ -14,6 +14,7 @@ import { DisplayValueByAttributeComponent } from './display-value-by-attribute.c
 import { DisplayRaDecComponent } from './display-ra-dec.component';
 import { DisplaySpectraComponent } from './display-spectra.component';
 import { DisplayImageComponent } from './display-image.component';
+import { DisplayJsonComponent } from './display-json.component';
 import { SpectraGraphComponent } from './spectra-graph/spectra-graph.component';
 
 export const dynamicComponents = [
@@ -24,5 +25,6 @@ export const dynamicComponents = [
     DisplayRaDecComponent,
     DisplaySpectraComponent,
     DisplayImageComponent,
+    DisplayJsonComponent,
     SpectraGraphComponent
 ];
diff --git a/client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.html b/client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..4f55c8c486dce3681a14bce17a62849927fd5fb6
--- /dev/null
+++ b/client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.html
@@ -0,0 +1,18 @@
+<accordion [isAnimated]="true">
+    <accordion-group [panelClass]="'custom-accordion'" #ag [isOpen]="isOpen" class="my-2">
+        <button class="btn btn-link btn-block clearfix pb-2" accordion-heading>
+            <span class="pull-left float-left">
+                {{ label }}
+                &nbsp;
+                <span *ngIf="ag.isOpen">
+                    <span class="fas fa-chevron-up"></span>
+                </span>
+                <span *ngIf="!ag.isOpen">
+                    <span class="fas fa-chevron-down"></span>
+                </span>
+            </span>
+        </button>
+
+        <ng-content></ng-content>
+    </accordion-group>
+</accordion>
diff --git a/client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.ts b/client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1f1ca950b9903be67ba9d4503ed886b52122d791
--- /dev/null
+++ b/client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.ts
@@ -0,0 +1,19 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import { Component, Input } from '@angular/core';
+
+@Component({
+    selector: 'app-dynamic-accordion',
+    templateUrl: 'dynamic-accordion.component.html'
+})
+export class DynamicAccordionComponent {
+    @Input() label: string;
+    @Input() isOpen: boolean;
+}
diff --git a/client/src/app/shared/dynamic-content/dynamic-components/index.ts b/client/src/app/shared/dynamic-content/dynamic-components/index.ts
index 233cdba737d25870b11d70086e16598c2aee92ac..cda8088ee7ad0e898cf865558cdba6c73e55bc98 100644
--- a/client/src/app/shared/dynamic-content/dynamic-components/index.ts
+++ b/client/src/app/shared/dynamic-content/dynamic-components/index.ts
@@ -8,7 +8,9 @@
  */
 
 import { DynamicRouterLinkComponent } from './dynamic-router-link.component';
+import { DynamicAccordionComponent } from './dynamic-accordion.component';
 
 export const dynamicComponents = [
-    DynamicRouterLinkComponent
+    DynamicRouterLinkComponent,
+    DynamicAccordionComponent
 ];
diff --git a/conf-dev/create-db.sh b/conf-dev/create-db.sh
index 17c4b5e160338a7b63482852aed4ccb551b16b4f..587a6f4044a83b619c924c2318cb7c60e4e777af 100644
--- a/conf-dev/create-db.sh
+++ b/conf-dev/create-db.sh
@@ -80,7 +80,7 @@ curl -d '{"id":9,"name":"fits_png","label":"fits_png","form_label":"fits_png","d
 curl -d '{"id":10,"name":"id_obspack","label":"id_obspack","form_label":"id_obspack","description":null,"primary_key":false,"type":"integer","search_type":null,"operator":null,"dynamic_operator":null,"min":null,"max":null,"options":null,"placeholder_min":null,"placeholder_max":null,"criteria_display":100,"output_display":100,"detail_renderer":null,"detail_renderer_config":null,"selected":true,"renderer":"link","renderer_config":{"href":"/instance/default/search/result/iris_obspack?s=100&a=1;2;3&c=1::eq::$value","display":"text","text":"$value","icon":"fas fa-link","blank":false},"order_by":true,"archive":false,"detail_display":100,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":4,"id_detail_output_category":null}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
 
 # Add observations detail config
-curl -d '{"content":"<h1 class=\"text-center\">\n    <app-display-value-by-attribute\n        [object]=\"context.object\"\n        [attributeList]=\"context.attributeList\"\n        [attributeId]=\"7\">\n    </app-display-value-by-attribute>\n</h1>\n<div class=\"row\">\n    <div class=\"col-md-8 col-sm-12 col-xs-12\">\n        <app-display-image\n            [object]=\"context.object\"\n            [attributeList]=\"context.attributeList\"\n            [dataset]=\"context.dataset\"\n            [attributeImageId]=\"9\"\n            [type]=\"'\''fits'\''\">\n        </app-display-image>\n    </div>\n    <div class=\"col-md-4 col-sm-12 col-xs-12\">\n        <app-display-ra-dec\n            [object]=\"context.object\"\n            [attributeList]=\"context.attributeList\"\n            [attributeRaId]=\"2\"\n            [attributeDecId]=\"3\">\n        </app-display-ra-dec>\n        <app-display-object-by-output-category\n            [object]=\"context.object\"\n            [dataset]=\"context.dataset\"\n            [instance]=\"context.instance\"\n            [attributeList]=\"context.attributeList\"\n            [outputCategoryList]=\"context.outputCategoryList\"\n            [queryParams]=\"context.queryParams\"\n            [outputCategoryId]=\"4\">\n        </app-display-object-by-output-category>\n    </div>\n</div>\n","style_sheet":"h1 {\n    color: red;\n}\n\n.panel-heading.card-header {\n    background-color: #dee2ff;\n}\n\n.panel .btn.btn-link .text-primary {\n    color: red !important;\n}\n"}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/detail-config
+curl -d '{"content":"<h1 class=\"text-center\">\n    <app-display-value-by-attribute\n        [object]=\"context.object\"\n        [attributeList]=\"context.attributeList\"\n        [attributeId]=\"7\">\n    </app-display-value-by-attribute>\n</h1>\n<div class=\"row\">\n    <div class=\"col-md-8 col-sm-12 col-xs-12\">\n        <app-display-image\n            [object]=\"context.object\"\n            [attributeList]=\"context.attributeList\"\n            [dataset]=\"context.dataset\"\n            [attributeImageId]=\"9\"\n            [type]=\"'\''fits'\''\">\n        </app-display-image>\n    </div>\n    <div class=\"col-md-4 col-sm-12 col-xs-12\">\n        <app-display-ra-dec\n            [object]=\"context.object\"\n            [attributeList]=\"context.attributeList\"\n            [attributeRaId]=\"2\"\n            [attributeDecId]=\"3\">\n        </app-display-ra-dec>\n        <app-display-object-by-output-category\n            [object]=\"context.object\"\n            [dataset]=\"context.dataset\"\n            [instance]=\"context.instance\"\n            [attributeList]=\"context.attributeList\"\n            [outputCategoryList]=\"context.outputCategoryList\"\n            [queryParams]=\"context.queryParams\"\n            [outputCategoryId]=\"4\"\n            [isOpened]=\"true\">\n        </app-display-object-by-output-category>\n    </div>\n</div>\n","style_sheet":"h1 {\n    color: red;\n}\n\n.panel-heading.card-header {\n    background-color: #dee2ff;\n}\n\n.panel .btn.btn-link .text-primary {\n    color: red !important;\n}\n"}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/detail-config
 
 # Add vvds_f02_udeep attributes
 curl -d '{"label":"Default","display":10,"opened":true}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/criteria-family