0

Update look and feel settings

by
Published Oct 17, 2025

Updates the look and feel settings for the site or for a single space. If custom settings exist, they are updated. If no custom settings exist, then a set of custom settings is created. Note, if a theme is selected for a space, the space look and feel settings are provided by the theme and cannot be overridden. **[Permissions](https://confluence.atlassian.com/x/_AozKw) required**: 'Admin' permission for the space.

Script confluence Verified

The script

Submitted by hugo697 Bun
Verified 235 days ago
1
//native
2
type Confluence = {
3
	email: string
4
	apiToken: string
5
	domain: string
6
}
7
/**
8
 * Update look and feel settings
9
 * Updates the look and feel settings for the site or for a single space.
10
If custom settings exist, they are updated. If no custom settings exist,
11
then a set of custom settings is created.
12

13
Note, if a theme is selected for a space, the space look and feel settings
14
are provided by the theme and cannot be overridden.
15

16
**[Permissions](https://confluence.atlassian.com/x/_AozKw) required**:
17
'Admin' permission for the space.
18
 */
19
export async function main(
20
	auth: Confluence,
21
	spaceKey: string | undefined,
22
	body: {
23
		headings: { color: string }
24
		links: { color: string }
25
		menus: { hoverOrFocus: { backgroundColor: string }; color: string }
26
		header: {
27
			backgroundColor: string
28
			button: { backgroundColor: string; color: string }
29
			primaryNavigation: {
30
				color: string
31
				highlightColor?: string
32
				hoverOrFocus: { backgroundColor: string; color: string }
33
			}
34
			secondaryNavigation: {
35
				color: string
36
				highlightColor?: string
37
				hoverOrFocus: { backgroundColor: string; color: string }
38
			}
39
			search: { backgroundColor: string; color: string }
40
		}
41
		horizontalHeader?: {
42
			backgroundColor: string
43
			button?: { backgroundColor: string; color: string }
44
			primaryNavigation: {
45
				color?: string
46
				highlightColor: string
47
				hoverOrFocus?: { backgroundColor?: string; color?: string }
48
			}
49
			secondaryNavigation?: {
50
				color: string
51
				highlightColor?: string
52
				hoverOrFocus: { backgroundColor: string; color: string }
53
			}
54
			search?: { backgroundColor: string; color: string }
55
		}
56
		content: {
57
			screen?: {
58
				background: string
59
				backgroundAttachment?: string
60
				backgroundBlendMode?: string
61
				backgroundClip?: string
62
				backgroundColor?: string
63
				backgroundImage?: string
64
				backgroundOrigin?: string
65
				backgroundPosition?: string
66
				backgroundRepeat?: string
67
				backgroundSize?: string
68
				layer?: { width?: string; height?: string }
69
				gutterTop?: string
70
				gutterRight?: string
71
				gutterBottom?: string
72
				gutterLeft?: string
73
			}
74
			container?: {
75
				background: string
76
				backgroundAttachment?: string
77
				backgroundBlendMode?: string
78
				backgroundClip?: string
79
				backgroundColor: string
80
				backgroundImage: string
81
				backgroundOrigin?: string
82
				backgroundPosition?: string
83
				backgroundRepeat?: string
84
				backgroundSize: string
85
				padding: string
86
				borderRadius: string
87
			}
88
			header?: {
89
				background: string
90
				backgroundAttachment?: string
91
				backgroundBlendMode?: string
92
				backgroundClip?: string
93
				backgroundColor: string
94
				backgroundImage: string
95
				backgroundOrigin?: string
96
				backgroundPosition?: string
97
				backgroundRepeat?: string
98
				backgroundSize: string
99
				padding: string
100
				borderRadius: string
101
			}
102
			body?: {
103
				background: string
104
				backgroundAttachment?: string
105
				backgroundBlendMode?: string
106
				backgroundClip?: string
107
				backgroundColor: string
108
				backgroundImage: string
109
				backgroundOrigin?: string
110
				backgroundPosition?: string
111
				backgroundRepeat?: string
112
				backgroundSize: string
113
				padding: string
114
				borderRadius: string
115
			}
116
		}
117
		bordersAndDividers: { color: string }
118
		spaceReference?: {}
119
	}
120
) {
121
	const url = new URL(`https://${auth.domain}/wiki/rest/api/settings/lookandfeel/custom`)
122
	for (const [k, v] of [['spaceKey', spaceKey]]) {
123
		if (v !== undefined && v !== '' && k !== undefined) {
124
			url.searchParams.append(k, v)
125
		}
126
	}
127
	const response = await fetch(url, {
128
		method: 'POST',
129
		headers: {
130
			'Content-Type': 'application/json',
131
			Authorization: 'Basic ' + btoa(`${auth.email}:${auth.apiToken}`)
132
		},
133
		body: JSON.stringify(body)
134
	})
135
	if (!response.ok) {
136
		const text = await response.text()
137
		throw new Error(`${response.status} ${text}`)
138
	}
139
	return await response.json()
140
}
141