File size: 7,825 Bytes
c24ea90
 
9d8447d
b8e1b6c
c24ea90
c1d1666
b8e1b6c
72cfb5a
b8e1b6c
597c2dc
 
a4b9560
c24ea90
9d8447d
 
 
 
 
c24ea90
f9074bc
c24ea90
9d8447d
c24ea90
9d8447d
c24ea90
9d8447d
a4b9560
9d8447d
 
 
 
a4b9560
597c2dc
c24ea90
 
 
 
 
 
 
 
 
a4b9560
597c2dc
 
 
a4b9560
 
 
 
 
 
597c2dc
a4b9560
 
 
 
597c2dc
a4b9560
597c2dc
 
c24ea90
597c2dc
9d8447d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
597c2dc
9d8447d
a4b9560
b8e1b6c
9d8447d
a4b9560
 
 
597c2dc
a4b9560
9e27095
a4b9560
9e27095
 
9d8447d
c24ea90
 
 
 
c59bbe1
c24ea90
 
 
 
 
 
 
 
c59bbe1
c24ea90
9d8447d
c24ea90
 
 
1c97ce0
a4b9560
c24ea90
 
 
 
 
 
 
 
 
 
b8e1b6c
f9074bc
c24ea90
 
 
 
 
b8e1b6c
c24ea90
 
 
 
 
 
f9074bc
52307d3
 
 
 
c59bbe1
c1d1666
 
 
9d8447d
c1d1666
9d8447d
c1d1666
 
 
 
 
 
 
 
 
 
 
 
 
9d8447d
c1d1666
1c97ce0
c1d1666
 
9d8447d
c1d1666
9d8447d
 
c1d1666
 
 
 
 
 
 
 
 
 
9d8447d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
{/* IMPORTS */}
import { Image } from 'astro:assets';
import placeholder from '../assets/image/placeholder.png';
import Sidenote from '../../components/Sidenote.astro';
import Wide from '../../components/Wide.astro';
import Note from '../../components/Note.astro';
import FullWidth from '../../components/FullWidth.astro';
import HtmlEmbed from '../../components/HtmlEmbed.astro';
import audioDemo from '../assets/audio/audio-example.wav';
import Accordion from '../../components/Accordion.astro';

## Writing your content

Once you have set up your project and started the development server, you can start writing your article.

### Content structure

Your **article** lives in **one and unique place**. The `content` folder.

<HtmlEmbed frameless src="demo/content-structure.html" /> 

### Article.mdx

The `article.mdx` file is the **main entry point** of your article which contains **2 main parts**.

<Note emoji="💡" variant="info">**MDX** is a mix of **Markdown** and **HTML/JSX**: write regular <a href="#markdown" >Markdown</a> and <a href="#components" >Components</a> when needed. Well describe the available options you can use later in this guide.</Note>


#### **Frontmatter**

Metadata and options for the article. Each of them is described in the table below.

<small className="muted">**Frontmatter** in app/src/content/article.mdx</small>
```mdx
---
title: "This is the main title"
subtitle: "This will be displayed just below the banner"
description: "A modern, MDX-first research article template with math, citations, and interactive figures."
published: "Feb 19, 2025"
tags:
  - research
  - template
authors:
  - name: "Thibaud Frere"
    url: "https://huggingface.co/tfrere"
    affiliations: [1]
  - name: "Alice Martin"
    url: "https://example.com/~alice"
    affiliations: [1, 2]
  - name: "Robert Brown"
    url: "https://example.com/~bob"
    affiliations: [2]
affiliations:
  - name: "Hugging Face"
    url: "https://huggingface.co"
  - name: "Example University"
    url: "https://example.edu"
doi: 10.1234/abcd.efgh
licence: Diagrams and text are licensed under <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank" rel="noopener noreferrer">CCBY 4.0</a> with the source available on <a href="https://huggingface.co/spaces/stfrere/research-article-template">Hugging Face</a>, unless noted otherwise. Figures reused from other sources are excluded and marked in their captions (Figure from …”).
seoThumbImage: "https://example.com/thumb.png"
tableOfContentsAutoCollapse: true
---
```

<Accordion title="Frontmatter fields">
| Field | Required | Notes | Type |
| --- | --- | --- | --- |
| title | Yes | Main title; supports line breaks with "\n" (falls back to "Untitled article") | string |
| subtitle | Yes | Shown just below the title | string |
| description | Yes | Used for SEO/meta description | string |
| published | Yes | e.g., "2025-02-19" or readable date | string/date |
| tags | No | List of keywords | string[] |
| authors | No | Affiliation indices refer to the `affiliations` list | `string[] or { name, url?, affiliations? }[]` |
| affiliations | No | Alias: `affiliation` (single or array) | `{ name, url? }[]` |
| doi | No | DOI identifier | string |
| licence | No | Rendered in footer; HTML supported | string (HTML allowed) |
| seoThumbImage | No | Overrides default OpenGraph image | string (URL) |
| tableOfContentsAutoCollapse | No | Controls TOC auto-collapse | boolean |
</Accordion>

#### **Content**

Your story. Write your content here.

<small className="muted">**Content** in app/src/content/article.mdx</small>
```mdx
import placeholder from '../assets/image/placeholder.png'
import ResponsiveImage from '../components/ResponsiveImage.astro'
import Sidenote from '../components/Sidenote.astro'

<Sidenote>
  This paragraph is written in Markdown. 
  <Fragment slot="aside">A short callout inserted via a component.</Fragment>
  </Sidenote>
<ResponsiveImage src={placeholder} alt="Sample image with optimization" />

This paragraph is also written in Markdown. 
```

#### Chapters

**If** your article becomes **too long** for one file, you can **organize** it into **separate chapters**.

Simply **create a new file** in the `app/src/content/chapters` **directory**.  
Then, **include** your new chapter in the main `article.mdx` like below.


<small className="muted">Example</small>
```mdx
import MyChapter from './chapters/my-chapter.mdx';

<MyChapter />
```
<small className="muted">You can see a living example here <a target="_blank" href="https://huggingface.co/spaces/tfrere/research-article-template/blob/main/app/src/content/chapters/best-pratices.mdx">app/src/content/chapters/best-pratices.mdx</a>.</small>

### **Table of contents**
 
The **Table of contents** is generated **automatically** from your **H2H4** headings. Keep headings **short** and **descriptive**; links work on **desktop** and **mobile**.

<Note variant="info" emoji="💡">You can make the table of contents collapse by changing the `tableOfContentsAutoCollapse` parameter in the <a href="#frontmatter">frontmatter</a>. Which is `true` by default.</Note>

### Theme

All **interactive elements** (buttons, inputs, cards, etc.) are themed with the **primary color** you choose.

You can **update this main color** to match your brand by changing the `--primary-color` variable in the `app/src/styles/_variables.css` file.

Use the **color picker** below to see how the primary color affects the theme.

#### Brand color

<Sidenote>
  <HtmlEmbed frameless src="demo/color-picker.html" />
  <Fragment slot="aside">
    You can use the color picker to select the right color.
    
    Here is an example of an <a href="#">interactive element</a>.
  </Fragment>
</Sidenote>


#### Color palettes

Here is a suggestion of **color palettes** for your **data visualizations** that align with your **brand identity**. These palettes are generated from your `--primary-color`.

<HtmlEmbed frameless src="demo/palettes.html" />
<br/>
**Use color with care.**
Color should rarely be the only channel of meaning.
Always pair it with text, icons, shape or position. The simulation helps you spot palettes and states that become indistinguishable for people with color‑vision deficiencies.

#### Using the palettes

##### CSS
Use the generated **CSS variables** to style elements (e.g., `color: var(--palette-categorical-1)`).

<Accordion title="Code example">
```css
/* Usage */
.series-a { color: var(--palette-categorical-1); }
.series-b { color: var(--palette-categorical-2); }
.heatmap-low  { background: var(--palette-sequential-1); }
.heatmap-high { background: var(--palette-sequential-6); }
.neg { color: var(--palette-diverging-1); }  /* left = primary */
.pos { color: var(--palette-diverging-6); }  /* right = complement */

/* Override size */
:root { --palette-count: 8; }                    /* global */
:root { --palette-diverging-count: 7; }          /* per palette */
```
</Accordion>

<Note variant="info" emoji='💡'>**CSS overrides** automatically trigger a **palette regeneration** via JS observers; no manual call is needed.</Note>

##### JS
Fetch arrays of colors via `window.ColorPalettes.getColors('categorical')`. To change sizes **at runtime**, set CSS vars (e.g., `document.documentElement.style.setProperty('--palette-count','8')`) and call `window.ColorPalettes.refresh()`.

<Accordion title="Code example">
  ```js
// Usage
const cat = window.ColorPalettes.getColors('categorical');
const seq = window.ColorPalettes.getColors('sequential');
const div = window.ColorPalettes.getColors('diverging');

// Override size (runtime)
document.documentElement.style.setProperty('--palette-count', '8');
document.documentElement.style.setProperty('--palette-diverging-count', '7');
window.ColorPalettes.refresh();
```
</Accordion>