<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yamuno</title>
    <description>The latest articles on DEV Community by Yamuno (@yamuno101).</description>
    <link>https://dev.to/yamuno101</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3894350%2F6becc7cb-035b-4a32-98a2-71b6857aa7fd.png</url>
      <title>DEV Community: Yamuno</title>
      <link>https://dev.to/yamuno101</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yamuno101"/>
    <language>en</language>
    <item>
      <title>5 Ways to Use HTML in Confluence Cloud (With Examples)</title>
      <dc:creator>Yamuno</dc:creator>
      <pubDate>Fri, 25 Sep 2026 07:33:16 +0000</pubDate>
      <link>https://dev.to/yamuno-software/5-ways-to-use-html-in-confluence-cloud-with-examples-3hcm</link>
      <guid>https://dev.to/yamuno-software/5-ways-to-use-html-in-confluence-cloud-with-examples-3hcm</guid>
      <description>&lt;h1&gt;
  
  
  5 Ways to Use HTML in Confluence Cloud (With Examples)
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; Confluence Cloud doesn't include an HTML macro. The one you may remember from Server and Data Center was never brought to Cloud, and even on Data Center it's disabled by default. In Cloud you have two options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The built-in &lt;strong&gt;iFrame macro&lt;/strong&gt; embeds another web page by URL. It can't run your own HTML, CSS or JavaScript, and many sites refuse to be embedded.&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;HTML macro app&lt;/strong&gt; from the Atlassian Marketplace adds a macro where you write your own code. It runs in a sandboxed frame, so it can't affect the rest of the page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This guide uses &lt;a href="https://dev.to/products/html-macro-for-confluence"&gt;HTML Macro+ for Confluence&lt;/a&gt;, which is free and runs on Atlassian Forge, but the ideas apply to any HTML macro. The code examples are split into HTML, CSS and JavaScript, matching the editor's three tabs.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you want to do&lt;/th&gt;
&lt;th&gt;Native Confluence Cloud&lt;/th&gt;
&lt;th&gt;With an HTML macro&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Style a section beyond the built-in panels&lt;/td&gt;
&lt;td&gt;Limited to panels, colors and layouts&lt;/td&gt;
&lt;td&gt;Any CSS inside the macro&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Embed a video, map or design file&lt;/td&gt;
&lt;td&gt;iFrame macro, if the site allows embedding&lt;/td&gt;
&lt;td&gt;Your own iframe, wrapped in your own layout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Show an existing &lt;code&gt;.html&lt;/code&gt; file&lt;/td&gt;
&lt;td&gt;Attach it as a download&lt;/td&gt;
&lt;td&gt;Render it on the page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add interactive elements&lt;/td&gt;
&lt;td&gt;Not possible&lt;/td&gt;
&lt;td&gt;Any JavaScript, in a sandbox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keep migrated Data Center HTML pages working&lt;/td&gt;
&lt;td&gt;Shows "unknown macro"&lt;/td&gt;
&lt;td&gt;Pages keep rendering&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  1. Style a section with custom CSS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When you need it:&lt;/strong&gt; a landing page for your space, a styled call-out, a grid of link cards, or brand colors that the built-in panels don't offer.&lt;/p&gt;

&lt;p&gt;One thing to know first: CSS in an HTML macro styles &lt;strong&gt;what is inside the macro&lt;/strong&gt;, not the whole Confluence page. That's by design, because the macro renders in its own sandboxed frame. It means your styles can't break the Confluence UI, and Confluence's styles can't break yours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"cards"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/wiki/spaces/ENG/pages/onboarding"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-kicker"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Start here&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Engineering onboarding&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Accounts, tools and your first week.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/wiki/spaces/ENG/pages/runbooks"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-kicker"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;On call&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Runbooks&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Step-by-step fixes for common incidents.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/wiki/spaces/ENG/pages/architecture"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-kicker"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Reference&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Architecture&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;How our services fit together.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.cards&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto-fit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;-apple-system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BlinkMacSystemFont&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;"Segoe UI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#dfe1e6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#172b4d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-color&lt;/span&gt; &lt;span class="m"&gt;0.15s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box-shadow&lt;/span&gt; &lt;span class="m"&gt;0.15s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0c66e4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;66&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.card-kicker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;letter-spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.04em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0c66e4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;h3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;17px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#44546f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Links inside the macro open through Confluence's own navigation, so internal &lt;code&gt;/wiki/...&lt;/code&gt; links behave like normal page links.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Embed videos, maps and design files
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When you need it:&lt;/strong&gt; a product demo video next to the release notes, an office map on the "Getting here" page, a Figma prototype in the design spec.&lt;/p&gt;

&lt;p&gt;The built-in iFrame macro works when the site allows embedding and you only need the embed itself. An HTML macro helps when you want the embed wrapped in your own layout, such as a responsive 16:9 frame with a caption, or several embeds side by side.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;figure&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"embed"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"frame"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt;
      &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.youtube.com/embed/VIDEO_ID"&lt;/span&gt;
      &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Release 4.2 walkthrough"&lt;/span&gt;
      &lt;span class="na"&gt;allowfullscreen&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;figcaption&amp;gt;&lt;/span&gt;Release 4.2 walkthrough (6 minutes)&lt;span class="nt"&gt;&amp;lt;/figcaption&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/figure&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.embed&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.frame&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;aspect-ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#091e42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.frame&lt;/span&gt; &lt;span class="nt"&gt;iframe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;inset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;figcaption&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;13px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#44546f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;VIDEO_ID&lt;/code&gt; with your video's ID. In HTML Macro+, unless your admin allows all domains, &lt;code&gt;youtube.com&lt;/code&gt; must be on the domain whitelist; until it is, the frame shows a "Content blocked" placeholder. The same applies to &lt;code&gt;google.com&lt;/code&gt; for Maps and &lt;code&gt;figma.com&lt;/code&gt; for Figma. See &lt;a href="https://dev.to/docs/html-macro-for-confluence/configuration/security-settings"&gt;security settings&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Show an existing HTML file on the page
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When you need it:&lt;/strong&gt; you already have HTML output from another tool, like a test coverage report, a notebook exported to HTML, a generated API reference or a one-page prototype. Attached to a page, it's just a download link that most readers never open.&lt;/p&gt;

&lt;p&gt;HTML Macro+ includes an &lt;strong&gt;HTML from Attachment&lt;/strong&gt; macro for this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Attach the &lt;code&gt;.html&lt;/code&gt; file to the Confluence page, or upload it from your computer in the macro.&lt;/li&gt;
&lt;li&gt;Insert the &lt;strong&gt;HTML from Attachment&lt;/strong&gt; macro and pick the file.&lt;/li&gt;
&lt;li&gt;Publish. The file renders on the page, sized to its content, with the same security rules as any other macro.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When the report is regenerated, replace the attachment to show the new version, with no copying and pasting of generated code.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Add interactivity with JavaScript
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When you need it:&lt;/strong&gt; content that's easier to read when readers can switch or filter it, such as tabs for different operating systems, a filterable list, a calculator or a chart.&lt;/p&gt;

&lt;p&gt;Here's a small tabbed panel. The same pattern works for any "show one of several" content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tabs"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tab-buttons"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"tablist"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"active"&lt;/span&gt; &lt;span class="na"&gt;data-tab=&lt;/span&gt;&lt;span class="s"&gt;"mac"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"tab"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;macOS&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;data-tab=&lt;/span&gt;&lt;span class="s"&gt;"windows"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"tab"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Windows&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;data-tab=&lt;/span&gt;&lt;span class="s"&gt;"linux"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"tab"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Linux&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tab-panel active"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"mac"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Install with Homebrew: &lt;span class="nt"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;brew install our-cli&lt;span class="nt"&gt;&amp;lt;/code&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tab-panel"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"windows"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Install with winget: &lt;span class="nt"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;winget install OurCo.Cli&lt;span class="nt"&gt;&amp;lt;/code&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tab-panel"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"linux"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Install with apt: &lt;span class="nt"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;sudo apt install our-cli&lt;span class="nt"&gt;&amp;lt;/code&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.tabs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;-apple-system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BlinkMacSystemFont&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;"Segoe UI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.tab-buttons&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;border-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#dfe1e6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.tab-buttons&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#44546f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.tab-buttons&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="nc"&gt;.active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0c66e4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;border-bottom-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0c66e4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.tab-panel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.tab-panel.active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;code&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f1f2f4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.tab-buttons button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.tab-buttons button, .tab-panel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For bigger examples, see &lt;a href="https://dev.to/blogs/how-to-embed-interactive-charts-confluence-html-macro"&gt;how to embed interactive charts with Chart.js&lt;/a&gt; and &lt;a href="https://dev.to/blogs/how-to-build-custom-status-dashboard-confluence"&gt;how to build a status dashboard&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Keep migrated Data Center HTML pages working
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When you need it:&lt;/strong&gt; you're moving from Confluence Server or Data Center, and some pages were built with the HTML macro. After migration, those pages show an "unknown macro" error in Cloud.&lt;/p&gt;

&lt;p&gt;HTML Macro+ recognizes both the Server/Data Center HTML macro and the Macro Toolbox for Cloud HTML macro. Once it's installed on your Cloud site, migrated pages render again without editing them one by one. You can then scan a space for the old macros, preview what will change, and convert them in bulk to the current macro. Pages stay live throughout.&lt;/p&gt;

&lt;p&gt;Before migrating, check which HTML macros use external scripts or images. Those domains need to be whitelisted in Cloud, or the content will show as blocked.&lt;/p&gt;




&lt;h2&gt;
  
  
  HTML macro not working?
&lt;/h2&gt;

&lt;p&gt;Most problems come down to a domain that isn't whitelisted, a script that runs before the page is ready, or restricted editor access. The &lt;a href="https://dev.to/docs/html-macro-for-confluence/troubleshooting"&gt;troubleshooting guide&lt;/a&gt; walks through each fix.&lt;/p&gt;




&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can Confluence Cloud render HTML?&lt;/strong&gt;&lt;br&gt;
Not natively. Confluence Cloud has no HTML macro. You can embed other web pages with the iFrame macro, or install an HTML macro app to render your own HTML, CSS and JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why doesn't Confluence Cloud have an HTML macro?&lt;/strong&gt;&lt;br&gt;
Letting any editor run their own code on a page is a security risk, especially cross-site scripting. HTML macro apps handle this by rendering code in a sandboxed frame and letting admins control which external sites can load.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I paste HTML into the Confluence editor?&lt;/strong&gt;&lt;br&gt;
Pasting copied web content keeps much of its formatting, but pasting raw HTML code shows it as text. To have code rendered, put it in an HTML macro.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it safe to use JavaScript in Confluence Cloud?&lt;/strong&gt;&lt;br&gt;
It depends on the app. Look for sandboxed rendering, an admin-controlled domain whitelist, and editor permissions so only trusted people can change code. HTML Macro+ has all three, and runs on Atlassian Forge, so content stays inside Atlassian.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does CSS in the macro change the rest of my Confluence page?&lt;/strong&gt;&lt;br&gt;
No. Styles apply only to the content inside the macro.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/products/html-macro-for-confluence"&gt;HTML Macro+ for Confluence&lt;/a&gt; is free on the Atlassian Marketplace. Start with the &lt;a href="https://dev.to/docs/html-macro-for-confluence/getting-started/installation"&gt;installation guide&lt;/a&gt;, then try any example above.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.atlassian.com/apps/1670180315/html-macro-for-confluence?hosting=cloud&amp;amp;tab=overview" rel="noopener noreferrer"&gt;Install HTML Macro+ — free on the Atlassian Marketplace&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>What Confluence's Built-In PDF Export Can't Do</title>
      <dc:creator>Yamuno</dc:creator>
      <pubDate>Wed, 23 Sep 2026 09:27:29 +0000</pubDate>
      <link>https://dev.to/yamuno-software/what-confluences-built-in-pdf-export-cant-do-3oke</link>
      <guid>https://dev.to/yamuno-software/what-confluences-built-in-pdf-export-cant-do-3oke</guid>
      <description>&lt;h1&gt;
  
  
  What Confluence's Built-In PDF Export Can't Do
&lt;/h1&gt;

&lt;p&gt;Confluence's native PDF export is fine when you need one page as a quick PDF. The moment you need more than that, a set of pages, a branded document, or a consistent format, you run into its limits fast. This is an honest list of what the built-in export cannot do, so you can tell when you have outgrown it.&lt;/p&gt;

&lt;p&gt;None of this is a knock on Confluence. The native export is a convenience feature, not a document tool. Knowing where it stops is the fastest way to decide whether you need something more.&lt;/p&gt;




&lt;h2&gt;
  
  
  It Exports One Page at a Time
&lt;/h2&gt;

&lt;p&gt;This is the big one. Native export is built around a single page. There is no way to select several pages, export a parent page together with all of its children, or export a whole space to PDF in one action.&lt;/p&gt;

&lt;p&gt;If you need to turn a 40-page documentation set into PDFs, native export means opening each page and exporting it individually, then dealing with 40 separate files. For anything beyond a handful of pages, that stops being practical.&lt;/p&gt;




&lt;h2&gt;
  
  
  No Cover Page
&lt;/h2&gt;

&lt;p&gt;There is no option to add a title page, a logo, a subtitle, or a document date to the front of the export. The PDF starts straight at the page content. For an internal draft that is fine. For a document going to a client or an executive, the missing cover is the first thing people notice.&lt;/p&gt;




&lt;h2&gt;
  
  
  No Custom Headers, Footers, or Page Numbers
&lt;/h2&gt;

&lt;p&gt;Native export gives you no control over headers and footers. You cannot add your company name, a document title, a confidentiality line, the export date, or page numbers. Everything a formal document usually carries in the margins is simply absent.&lt;/p&gt;




&lt;h2&gt;
  
  
  No Watermarks
&lt;/h2&gt;

&lt;p&gt;There is no way to stamp a PDF with "DRAFT", "CONFIDENTIAL", or "FOR REVIEW". For teams that share documents externally or work under compliance rules, a watermark is often a requirement rather than a nicety, and native export does not offer one.&lt;/p&gt;




&lt;h2&gt;
  
  
  No Reusable Templates
&lt;/h2&gt;

&lt;p&gt;Every native export is a one-off. There is no way to save a format and apply it again, so two exports of the same page a week apart can look different, and two people on the same team have no shared standard to work from. Consistency has to be enforced by hand, which means it usually is not.&lt;/p&gt;




&lt;h2&gt;
  
  
  No Table of Contents
&lt;/h2&gt;

&lt;p&gt;A single-page native export has no navigation. There is no auto-generated table of contents built from your headings, which is exactly what a longer document needs to be readable once it is a PDF.&lt;/p&gt;




&lt;h2&gt;
  
  
  Limited Control Over Layout
&lt;/h2&gt;

&lt;p&gt;Native export gives you no say over fonts, margins, line spacing, or page breaks. Wide tables and large images are handled with whatever defaults Confluence applies, and you cannot adjust them. When the output does not fit the page well, there is no setting to fix it.&lt;/p&gt;




&lt;h2&gt;
  
  
  When You've Outgrown Native Export
&lt;/h2&gt;

&lt;p&gt;If you only ever export the occasional single page for your own use, the built-in export is genuinely all you need, and there is no reason to add an app.&lt;/p&gt;

&lt;p&gt;You have outgrown it the moment any of these becomes true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to export &lt;strong&gt;more than a few pages at once&lt;/strong&gt;, or a whole space&lt;/li&gt;
&lt;li&gt;The PDF is &lt;strong&gt;going to someone outside your team&lt;/strong&gt;, so it needs a cover and branding&lt;/li&gt;
&lt;li&gt;You are exporting for &lt;strong&gt;compliance or retention&lt;/strong&gt;, so it needs watermarks, page numbers, and a repeatable format&lt;/li&gt;
&lt;li&gt;You want &lt;strong&gt;every export to look the same&lt;/strong&gt;, which means templates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the point where a dedicated export tool earns its place. &lt;a href="https://marketplace.atlassian.com/apps/726790413" rel="noopener noreferrer"&gt;PDF Exporter for Confluence&lt;/a&gt; adds exactly what the native export leaves out: bulk export of multiple pages, page trees, and whole spaces; cover pages, headers, footers, and watermarks; a table of contents; and reusable templates so every export is consistent. It runs on Atlassian Forge, so nothing leaves your instance.&lt;/p&gt;

&lt;p&gt;For a step-by-step walkthrough, see &lt;a href="https://dev.to/blogs/how-to-export-confluence-to-pdf"&gt;How to Export Confluence Pages to PDF&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Install &lt;a href="https://marketplace.atlassian.com/apps/726790413" rel="noopener noreferrer"&gt;PDF Exporter for Confluence&lt;/a&gt; from the Atlassian Marketplace.&lt;/p&gt;

&lt;p&gt;Full documentation is at &lt;a href="https://dev.to/docs/pdf-exporter-for-confluence"&gt;/docs/pdf-exporter-for-confluence&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Questions? Reach out via our &lt;a href="https://yamuno.atlassian.net/servicedesk/customer/portals" rel="noopener noreferrer"&gt;support portal&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How Compliance Teams Export Confluence Content to PDF</title>
      <dc:creator>Yamuno</dc:creator>
      <pubDate>Wed, 29 Jul 2026 10:41:07 +0000</pubDate>
      <link>https://dev.to/yamuno-software/how-compliance-teams-export-confluence-content-to-pdf-25k0</link>
      <guid>https://dev.to/yamuno-software/how-compliance-teams-export-confluence-content-to-pdf-25k0</guid>
      <description>&lt;h1&gt;
  
  
  How Compliance Teams Export Confluence Content to PDF
&lt;/h1&gt;

&lt;p&gt;Compliance teams deal with a recurring documentation challenge: processes, policies, and controls are maintained in Confluence (where they're easy to update and collaborate on), but auditors, regulators, and legal teams need point-in-time PDF snapshots they can review, sign off on, or attach to a submission.&lt;/p&gt;

&lt;p&gt;Confluence's native PDF export works for basic cases but has no provisions for the requirements that matter in compliance contexts: consistent formatting across all exported documents, watermarks for draft and confidential status, a clear record of what was exported and when, and reusable templates that ensure every export looks the same regardless of who ran it.&lt;/p&gt;

&lt;p&gt;This guide covers how to set up a compliant export workflow using &lt;a href="https://marketplace.atlassian.com/apps/726790413" rel="noopener noreferrer"&gt;PDF Exporter for Confluence&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Requirements for Compliance Exports
&lt;/h2&gt;

&lt;p&gt;Before configuring anything, it helps to be specific about what compliance exports actually need:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consistency&lt;/strong&gt; — every exported document should look the same. If an auditor compares two policy documents and they have different headers, different page layouts, or different cover pages, it raises questions about process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Document identification&lt;/strong&gt; — the PDF should identify itself: what it is, who produced it, what classification it carries (confidential, internal, public). This information should be in the header, footer, or cover page — not just in the filename.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watermarks where required&lt;/strong&gt; — draft documents under review must be marked as drafts. Confidential documents must be visibly marked. Documents that have been superseded should carry an "ARCHIVED" watermark.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Completeness&lt;/strong&gt; — when a compliance submission requires a set of documents (all policies in a space, all runbooks for a system), the export should cover the complete set, not a manually assembled selection that could be incomplete.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 — Set Up Compliance Templates
&lt;/h2&gt;

&lt;p&gt;Create dedicated templates for compliance use cases. Log into Confluence as an admin, go to &lt;strong&gt;Settings → PDF Exporter → Templates&lt;/strong&gt;, and create the following:&lt;/p&gt;

&lt;h3&gt;
  
  
  Template 1: "Policy — Current"
&lt;/h3&gt;

&lt;p&gt;For active, approved policies shared with auditors or regulators.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cover style:&lt;/strong&gt; Executive (minimal, formal)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accent color:&lt;/strong&gt; Company primary color&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logo:&lt;/strong&gt; Company logo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Author:&lt;/strong&gt; "Compliance Team" or department name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Header:&lt;/strong&gt; Document title, centered&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Footer (left):&lt;/strong&gt; "Confidential — [Company Name]"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Footer (right):&lt;/strong&gt; Page number (&lt;code&gt;Page 1 of 10&lt;/code&gt; format)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watermark:&lt;/strong&gt; Disabled&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Table of contents:&lt;/strong&gt; Enabled, depth 2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Page breaks:&lt;/strong&gt; Before H1&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Template 2: "Policy — Draft"
&lt;/h3&gt;

&lt;p&gt;For documents under internal review before approval.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Same as "Policy — Current" except:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watermark:&lt;/strong&gt; Enabled, text "DRAFT", opacity 0.20&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subtitle:&lt;/strong&gt; "For Internal Review Only"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Template 3: "Compliance Archive"
&lt;/h3&gt;

&lt;p&gt;For historical snapshots being archived or submitted as evidence of past state.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Same as "Policy — Current" except:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watermark:&lt;/strong&gt; Enabled, text "ARCHIVED", opacity 0.15&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Footer (left):&lt;/strong&gt; "Archived — [Company Name] — [Date]"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: the footer date needs to be manually updated when creating each archive export, since templates don't have dynamic date fields.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2 — Export Individual Policies
&lt;/h2&gt;

&lt;p&gt;For exporting a single policy document:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the policy page in Confluence&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;•••&lt;/strong&gt; → &lt;strong&gt;Export to PDF&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select the appropriate template ("Policy — Current" for finalized, "Policy — Draft" for review)&lt;/li&gt;
&lt;li&gt;Use the &lt;strong&gt;Preview&lt;/strong&gt; option to verify the cover page, watermark, and footer before downloading&lt;/li&gt;
&lt;li&gt;Download the PDF&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The preview step is important for compliance exports — it takes 15 seconds and catches issues (wrong watermark status, missing logo) that would be unprofessional in a submission.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Export a Complete Policy Set
&lt;/h2&gt;

&lt;p&gt;When an audit requires a complete set of documents — all security policies, all change management procedures, all GDPR-related documentation — use the space export to capture everything in scope.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;From the Confluence global navigation, open &lt;strong&gt;Apps → PDF Exporter for Confluence&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The page tree for the current space is displayed&lt;/li&gt;
&lt;li&gt;Navigate the tree and select all pages in scope&lt;/li&gt;
&lt;li&gt;Uncheck any pages that are internal working drafts not intended for the submission&lt;/li&gt;
&lt;li&gt;Select the "Policy — Current" template&lt;/li&gt;
&lt;li&gt;Export&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The download is a ZIP file containing one PDF per page. The ZIP structure mirrors the Confluence page hierarchy — auditors can navigate it like a folder structure.&lt;/p&gt;

&lt;p&gt;If the submission requires a single combined document rather than individual PDFs, export a parent page with all child pages included — the output is still individual PDFs per page, but they can be manually combined using any PDF tool if a single-file format is required.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4 — Archive Snapshots
&lt;/h2&gt;

&lt;p&gt;Compliance often requires preserving point-in-time snapshots of policies — what did the data retention policy say on January 1, 2026? The page in Confluence may have been updated since then.&lt;/p&gt;

&lt;p&gt;The workflow for archive snapshots:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When a policy is approved, export it immediately using the "Policy — Current" template&lt;/li&gt;
&lt;li&gt;Store the PDF in a designated archive location (shared drive, document management system)&lt;/li&gt;
&lt;li&gt;When the policy is updated and re-approved, export the updated version and archive the previous one using the "Compliance Archive" template (which adds the ARCHIVED watermark)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This gives you a complete versioned record: the current approved policy in Confluence, and a series of archived PDFs showing the policy's state at each approval milestone.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5 — Document the Export Process Itself
&lt;/h2&gt;

&lt;p&gt;For audits where the reviewer may ask "how do you ensure the exported documents are accurate?", document the export process itself in Confluence:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which templates are used for which document types&lt;/li&gt;
&lt;li&gt;Who is authorized to run compliance exports&lt;/li&gt;
&lt;li&gt;How and where archived PDFs are stored&lt;/li&gt;
&lt;li&gt;The review/preview step that happens before each export&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This process documentation can itself be exported to PDF using the same templates. An auditor asking "what's your document control process?" gets a PDF produced by the same process it describes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Compliance Scenarios
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;SOC 2 audit preparation:&lt;/strong&gt; Export all security policies (access control, change management, incident response, business continuity) using the "Policy — Current" template. The cover page identifies the document; the consistent header and footer identify the producing organization; the table of contents makes it navigable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GDPR documentation submission:&lt;/strong&gt; Export privacy policy, data processing agreements, and DPIA records. Use the "Policy — Current" template. Ensure the footer carries the confidentiality classification appropriate for GDPR documentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ISO 27001 evidence collection:&lt;/strong&gt; Export control documentation, risk assessment records, and procedure documents. For evidence of past state ("what did your risk assessment look like during the audit period?"), use archived snapshots from the archive workflow above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Legal hold:&lt;/strong&gt; When content in Confluence becomes subject to a legal hold, export the relevant pages immediately using the "Compliance Archive" template and store them outside Confluence where they can be produced on request.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://marketplace.atlassian.com/apps/726790413" rel="noopener noreferrer"&gt;Install PDF Exporter for Confluence →&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/docs/pdf-exporter-for-confluence"&gt;Read the documentation →&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Bulk Import Markdown Files into Confluence</title>
      <dc:creator>Yamuno</dc:creator>
      <pubDate>Thu, 23 Jul 2026 10:24:54 +0000</pubDate>
      <link>https://dev.to/yamuno-software/how-to-bulk-import-markdown-files-into-confluence-1pgn</link>
      <guid>https://dev.to/yamuno-software/how-to-bulk-import-markdown-files-into-confluence-1pgn</guid>
      <description>&lt;h1&gt;
  
  
  How to Bulk Import Markdown Files into Confluence
&lt;/h1&gt;

&lt;p&gt;If you're migrating documentation from GitHub, GitLab, Notion, or a static site generator, you're probably looking at more than a handful of markdown files. Importing them one at a time into Confluence isn't viable at scale. This guide covers how to bulk import — dozens or hundreds of files at once — with the page hierarchy, images, and formatting preserved.&lt;/p&gt;




&lt;h2&gt;
  
  
  What "Bulk Import" Means in Practice
&lt;/h2&gt;

&lt;p&gt;A bulk import takes a ZIP archive containing markdown files and a folder structure, and creates a matching set of Confluence pages with the same hierarchy. A folder in the ZIP becomes a parent page in Confluence. A markdown file becomes a Confluence page. Images referenced in the markdown are uploaded as attachments and linked correctly in the page content.&lt;/p&gt;

&lt;p&gt;The result: a ZIP with 80 files becomes 80 Confluence pages in the right hierarchy without anyone touching each one individually.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 — Prepare Your Markdown Files
&lt;/h2&gt;

&lt;p&gt;Install &lt;a href="https://marketplace.atlassian.com/apps/1228589694" rel="noopener noreferrer"&gt;Markdown Importer for Confluence&lt;/a&gt; from the Atlassian Marketplace.&lt;/p&gt;

&lt;p&gt;Before creating the ZIP, organize your markdown files in the folder structure you want reflected in Confluence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docs/
├── getting-started.md
├── installation.md
├── configuration/
│   ├── basic-setup.md
│   ├── advanced-options.md
│   └── environment-variables.md
├── how-to/
│   ├── first-steps.md
│   └── common-tasks.md
└── reference/
    ├── api.md
    └── cli.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each folder will become a parent page in Confluence. The nesting can be as deep as you need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File naming:&lt;/strong&gt; The importer uses the markdown filename (without the &lt;code&gt;.md&lt;/code&gt; extension) as the Confluence page title. Hyphens are replaced with spaces and the first letter is capitalized — &lt;code&gt;getting-started.md&lt;/code&gt; becomes "Getting Started." If a file has a &lt;code&gt;title&lt;/code&gt; field in its frontmatter, that takes precedence over the filename.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2 — Add Frontmatter (Optional but Recommended)
&lt;/h2&gt;

&lt;p&gt;YAML frontmatter at the top of each markdown file gives the importer more information to work with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Advanced&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Configuration&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Options"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="c1"&gt;# Advanced Configuration Options&lt;/span&gt;

&lt;span class="s"&gt;Rest of the content...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a &lt;code&gt;title&lt;/code&gt; is present, the importer uses it as the Confluence page title. This lets you have descriptive filenames in the repo while setting human-readable titles in Confluence.&lt;/p&gt;

&lt;p&gt;Other frontmatter fields are not processed by the importer but are preserved if you later export back to markdown.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Include Images in the ZIP
&lt;/h2&gt;

&lt;p&gt;If your markdown files reference local images, include them in the ZIP alongside the markdown files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docs/
├── getting-started.md          # references ./images/screenshot.png
├── images/
│   └── screenshot.png
└── reference/
    ├── api.md                  # references ../images/api-flow.png
    └── cli.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Image references in the markdown should be relative paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;![&lt;/span&gt;&lt;span class="nv"&gt;Screenshot&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;./images/screenshot.png&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The importer uploads the images as Confluence attachments and updates the references in the page content to point to the uploaded attachments. The relative path structure is resolved relative to the markdown file's location in the ZIP.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4 — Create the ZIP Archive
&lt;/h2&gt;

&lt;p&gt;On macOS or Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/your
zip &lt;span class="nt"&gt;-r&lt;/span&gt; docs-import.zip docs/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Windows (PowerShell):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Compress-Archive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;\docs\&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-DestinationPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;\docs-import.zip&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ZIP should contain the root folder (&lt;code&gt;docs/&lt;/code&gt;), not just the contents. This preserves the top-level folder name, which becomes the title of the root-level parent page if you're importing the whole tree.&lt;/p&gt;

&lt;p&gt;If you'd rather the import start with the contents of the folder (not the folder itself as a parent page), zip the contents directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/your/docs
zip &lt;span class="nt"&gt;-r&lt;/span&gt; ../docs-import.zip &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5 — Import the ZIP
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to the Confluence page that should be the parent of the imported content&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;•••&lt;/strong&gt; (More actions) → &lt;strong&gt;Markdown Importer &amp;amp; Exporter&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Upload&lt;/strong&gt; and select your ZIP archive&lt;/li&gt;
&lt;li&gt;Configure the import options:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Page Hierarchy&lt;/strong&gt; — enable this to create parent/child pages from the folder structure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overwrite existing pages&lt;/strong&gt; — enable if you're re-importing and want to update pages that already exist&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Import&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A progress indicator shows pages being processed. For large imports (100+ pages), this may take a few minutes. The importer processes pages in small batches to avoid hitting Confluence API rate limits.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6 — Import from the Global Apps Menu (Multiple Spaces)
&lt;/h2&gt;

&lt;p&gt;If you're importing into multiple Confluence spaces in one operation, use the global access point instead of the page-level entry:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Apps&lt;/strong&gt; in the Confluence global navigation&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Markdown Importer &amp;amp; Exporter&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Choose the target space and parent page from the dropdowns&lt;/li&gt;
&lt;li&gt;Upload your ZIP and configure options&lt;/li&gt;
&lt;li&gt;Import&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Admins can use this to import documentation across multiple spaces without navigating to each target page individually.&lt;/p&gt;




&lt;h2&gt;
  
  
  Handling Large Imports
&lt;/h2&gt;

&lt;p&gt;For very large imports (500+ pages), consider splitting the ZIP by section and importing in batches. This makes it easier to review the output after each batch and fix any issues before continuing.&lt;/p&gt;

&lt;p&gt;After the first batch, check a few imported pages to verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Page titles are correct&lt;/li&gt;
&lt;li&gt;Images are displaying (not showing broken links)&lt;/li&gt;
&lt;li&gt;The hierarchy is correct in the page tree&lt;/li&gt;
&lt;li&gt;Formatting (code blocks, tables, headings) rendered properly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If something is off, it's usually a consistent issue (like image paths being wrong) that you can fix across all remaining files before the next batch.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Issues
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Broken image references:&lt;/strong&gt; Usually caused by images being outside the ZIP or using absolute paths instead of relative paths. Fix the markdown to use relative paths and ensure images are inside the ZIP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wrong page titles:&lt;/strong&gt; The filename is being used instead of frontmatter. Add &lt;code&gt;title:&lt;/code&gt; frontmatter to the affected files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hierarchy not matching the folder structure:&lt;/strong&gt; Page Hierarchy option was not enabled during import. Re-import with the option enabled — use "Overwrite" to update the existing pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Import stops partway through:&lt;/strong&gt; Likely a rate limit from the Confluence API. Wait a few minutes and re-import the remaining files. Use "Overwrite" so already-imported pages are updated rather than duplicated.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://marketplace.atlassian.com/apps/1228589694" rel="noopener noreferrer"&gt;Install Markdown Importer for Confluence →&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/docs/markdown-importer-for-confluence"&gt;Read the documentation →&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Build a Custom Status Dashboard in Confluence</title>
      <dc:creator>Yamuno</dc:creator>
      <pubDate>Sat, 18 Jul 2026 09:35:48 +0000</pubDate>
      <link>https://dev.to/yamuno-software/how-to-build-a-custom-status-dashboard-in-confluence-1228</link>
      <guid>https://dev.to/yamuno-software/how-to-build-a-custom-status-dashboard-in-confluence-1228</guid>
      <description>&lt;h1&gt;
  
  
  How to Build a Custom Status Dashboard in Confluence
&lt;/h1&gt;

&lt;p&gt;Project status pages in Confluence often end up as paragraphs of text that nobody reads. A wall of prose with a last-updated date from three weeks ago doesn't communicate project health — it communicates that someone was busy when they wrote it.&lt;/p&gt;

&lt;p&gt;A visual status dashboard that shows RAG indicators, progress percentages, and days until key milestones is faster to read and easier to maintain. This guide walks through building one using &lt;a href="https://marketplace.atlassian.com/apps/1670180315/html-macro-for-confluence-free?hosting=cloud&amp;amp;tab=overview" rel="noopener noreferrer"&gt;HTML Macro for Confluence&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What We're Building
&lt;/h2&gt;

&lt;p&gt;A status dashboard with four components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;RAG status cards&lt;/strong&gt; — one per workstream, color-coded by health&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progress bars&lt;/strong&gt; — percentage complete for each initiative&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Milestone countdown&lt;/strong&gt; — days until the next key date&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metric tiles&lt;/strong&gt; — key numbers at a glance&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each component is a separate HTML Macro on the page. You can use all four or just the ones that fit your context.&lt;/p&gt;




&lt;h2&gt;
  
  
  Component 1 — RAG Status Cards
&lt;/h2&gt;

&lt;p&gt;A row of status cards, one per workstream. Color-coded: green = on track, amber = at risk, red = blocked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:flex; gap:16px; flex-wrap:wrap; font-family:sans-serif;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"flex:1; min-width:180px; padding:20px; border-radius:12px; background:#f0fdf4; border:1px solid #86efac;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:12px; font-weight:600; text-transform:uppercase; letter-spacing:0.08em; color:#15803d; margin-bottom:8px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Backend API&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:flex; align-items:center; gap:8px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"width:12px; height:12px; border-radius:50%; background:#22c55e; box-shadow:0 0 6px #22c55e88;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:15px; font-weight:700; color:#1e293b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;On Track&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin-top:8px; font-size:13px; color:#64748b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Sprint 3 of 4 complete&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"flex:1; min-width:180px; padding:20px; border-radius:12px; background:#fffbeb; border:1px solid #fcd34d;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:12px; font-weight:600; text-transform:uppercase; letter-spacing:0.08em; color:#92400e; margin-bottom:8px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Mobile App&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:flex; align-items:center; gap:8px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"width:12px; height:12px; border-radius:50%; background:#f59e0b; box-shadow:0 0 6px #f59e0b88;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:15px; font-weight:700; color:#1e293b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;At Risk&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin-top:8px; font-size:13px; color:#64748b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Design review delayed 3 days&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"flex:1; min-width:180px; padding:20px; border-radius:12px; background:#fef2f2; border:1px solid #fca5a5;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:12px; font-weight:600; text-transform:uppercase; letter-spacing:0.08em; color:#b91c1c; margin-bottom:8px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Integrations&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:flex; align-items:center; gap:8px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"width:12px; height:12px; border-radius:50%; background:#ef4444; box-shadow:0 0 6px #ef444488;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:15px; font-weight:700; color:#1e293b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Blocked&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin-top:8px; font-size:13px; color:#64748b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Waiting on vendor API access&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;To update a status:&lt;/strong&gt; change &lt;code&gt;#22c55e&lt;/code&gt; → &lt;code&gt;#f59e0b&lt;/code&gt; → &lt;code&gt;#ef4444&lt;/code&gt; on both the dot color and the card background/border colors, and update the label and note text.&lt;/p&gt;




&lt;h2&gt;
  
  
  Component 2 — Progress Bars
&lt;/h2&gt;

&lt;p&gt;Visual progress indicators for each initiative. The percentage is shown as a filled bar with a label.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-family:sans-serif; max-width:560px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin-bottom:18px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:flex; justify-content:space-between; margin-bottom:6px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:14px; font-weight:600; color:#1e293b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Backend API&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:14px; font-weight:700; color:#6366f1;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;75%&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background:#e2e8f0; border-radius:99px; height:8px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background:#6366f1; width:75%; height:8px; border-radius:99px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin-bottom:18px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:flex; justify-content:space-between; margin-bottom:6px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:14px; font-weight:600; color:#1e293b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Mobile App&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:14px; font-weight:700; color:#f59e0b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;48%&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background:#e2e8f0; border-radius:99px; height:8px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background:#f59e0b; width:48%; height:8px; border-radius:99px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin-bottom:18px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:flex; justify-content:space-between; margin-bottom:6px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:14px; font-weight:600; color:#1e293b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Integrations&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:14px; font-weight:700; color:#ef4444;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;20%&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background:#e2e8f0; border-radius:99px; height:8px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background:#ef4444; width:20%; height:8px; border-radius:99px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;To update:&lt;/strong&gt; change the &lt;code&gt;width&lt;/code&gt; percentage on the filled div and the number in the label. Match the bar color to the RAG status from Component 1.&lt;/p&gt;




&lt;h2&gt;
  
  
  Component 3 — Milestone Countdown
&lt;/h2&gt;

&lt;p&gt;A JavaScript countdown to the next key date.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-family:sans-serif; display:inline-flex; align-items:center; gap:24px; padding:20px 28px; background:#f8fafc; border:1px solid #e2e8f0; border-radius:14px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:12px; font-weight:600; text-transform:uppercase; letter-spacing:0.08em; color:#64748b; margin-bottom:4px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Launch Date&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:14px; color:#1e293b; font-weight:500;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;August 15, 2026&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:flex; gap:16px; text-align:center;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"cd-days"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:40px; font-weight:800; color:#1e293b; line-height:1;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;--&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:11px; color:#94a3b8; text-transform:uppercase; letter-spacing:0.06em; margin-top:3px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Days&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:32px; color:#e2e8f0; font-weight:300; padding-top:4px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;:&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"cd-hours"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:40px; font-weight:800; color:#1e293b; line-height:1;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;--&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:11px; color:#94a3b8; text-transform:uppercase; letter-spacing:0.06em; margin-top:3px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hours&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2026-08-15T09:00:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cd-days&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cd-hours&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cd-days&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;86400000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cd-hours&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;86400000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;3600000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the date string in &lt;code&gt;new Date("2026-08-15T09:00:00")&lt;/code&gt; to your actual milestone date.&lt;/p&gt;




&lt;h2&gt;
  
  
  Component 4 — Metric Tiles
&lt;/h2&gt;

&lt;p&gt;Key numbers at a glance — open issues, completed stories, team size, or any other project metric.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:flex; gap:16px; flex-wrap:wrap; font-family:sans-serif;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"flex:1; min-width:140px; padding:20px; border-radius:12px; background:#fff; border:1px solid #e2e8f0; text-align:center;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:36px; font-weight:800; color:#6366f1;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;34&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:13px; color:#64748b; margin-top:4px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Issues Closed&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"flex:1; min-width:140px; padding:20px; border-radius:12px; background:#fff; border:1px solid #e2e8f0; text-align:center;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:36px; font-weight:800; color:#22c55e;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;12&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:13px; color:#64748b; margin-top:4px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Open Bugs&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"flex:1; min-width:140px; padding:20px; border-radius:12px; background:#fff; border:1px solid #e2e8f0; text-align:center;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:36px; font-weight:800; color:#f59e0b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;3&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:13px; color:#64748b; margin-top:4px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Blocked Items&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"flex:1; min-width:140px; padding:20px; border-radius:12px; background:#fff; border:1px solid #e2e8f0; text-align:center;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:36px; font-weight:800; color:#1e293b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;8&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:13px; color:#64748b; margin-top:4px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Team Members&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;To update:&lt;/strong&gt; change the number inside the large &lt;code&gt;div&lt;/code&gt; and the label below it. Update the color to reflect the health of the metric if relevant (green for good, amber for concerning, red for problem).&lt;/p&gt;




&lt;h2&gt;
  
  
  Putting It Together
&lt;/h2&gt;

&lt;p&gt;On the Confluence page, add four HTML Macro blocks stacked vertically:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;RAG Status Cards&lt;/strong&gt; at the top&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metric Tiles&lt;/strong&gt; below&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progress Bars&lt;/strong&gt; in the middle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Milestone Countdown&lt;/strong&gt; at the bottom&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add a native Confluence "Last Updated" text or use the &lt;code&gt;@date&lt;/code&gt; mention to timestamp the page. This tells readers whether the data is current.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weekly update workflow:&lt;/strong&gt; At the start of each week, open the page, click Edit, and update the RAG color/label in each card, the progress bar percentages, and the metric numbers. It takes 5–10 minutes and the page communicates project health clearly to anyone who opens it.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://marketplace.atlassian.com/apps/1670180315/html-macro-for-confluence-free?hosting=cloud&amp;amp;tab=overview" rel="noopener noreferrer"&gt;Install HTML Macro for Confluence — free on the Atlassian Marketplace&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Jira Reporting for Product Managers: Charts, Metrics, and Dashboards</title>
      <dc:creator>Yamuno</dc:creator>
      <pubDate>Tue, 14 Jul 2026 10:00:30 +0000</pubDate>
      <link>https://dev.to/yamuno-software/jira-reporting-for-product-managers-charts-metrics-and-dashboards-4a1e</link>
      <guid>https://dev.to/yamuno-software/jira-reporting-for-product-managers-charts-metrics-and-dashboards-4a1e</guid>
      <description>&lt;h1&gt;
  
  
  Jira Reporting for Product Managers: Charts, Metrics, and Dashboards
&lt;/h1&gt;

&lt;p&gt;Product managers and engineering teams look at the same Jira data and need completely different things from it. Engineering wants sprint health, cycle time, and blocked issue counts. Product management wants feature progress, release readiness, customer-reported bug trends, and backlog composition.&lt;/p&gt;

&lt;p&gt;Most Jira dashboards are set up by or for engineering teams. If you're a PM who has tried to get useful reporting out of Jira and ended up with a page full of gadgets that don't answer your actual questions, this guide is for you.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Four Questions a PM Dashboard Should Answer
&lt;/h2&gt;

&lt;p&gt;Before picking any chart, start with the questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What's the state of the current release?&lt;/strong&gt; — Feature completion, open bugs, scope changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What's the trend for customer-reported issues?&lt;/strong&gt; — Bug volume over time, resolution rate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What does the backlog look like?&lt;/strong&gt; — Priority distribution, backlog by product area&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What shipped recently?&lt;/strong&gt; — Completed features, closed bugs, release notes fodder&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your dashboard can answer these four questions without anyone opening a filter or running a query, it's doing its job.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chart 1 — Release Progress Bar
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The question:&lt;/strong&gt; How far along are we in the current release?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chart type: Bar (stacked)&lt;/li&gt;
&lt;li&gt;Filter: &lt;code&gt;fixVersion = "Your Release Name"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Group by: Status&lt;/li&gt;
&lt;li&gt;Show: To Do, In Progress, In Review, Done as stacked segments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A stacked bar with one bar showing all four statuses tells you at a glance: how much is done, how much is in flight, and how much hasn't started. When the Done segment is 80%+ of the bar with a week left in the release, you're in good shape. When To Do still represents 40% with the release date looming, you have a scope problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JQL filter:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;YOURPROJECT&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;fixVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;"v2.4"&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;issueType&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Story&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Chart 2 — Customer-Reported Bug Trend
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The question:&lt;/strong&gt; Is the volume of customer-reported bugs stable, increasing, or decreasing?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chart type: Line&lt;/li&gt;
&lt;li&gt;Filter: &lt;code&gt;label = "customer-reported"&lt;/code&gt; (or however your team tags customer bugs)&lt;/li&gt;
&lt;li&gt;X-axis: Week or month&lt;/li&gt;
&lt;li&gt;Y-axis: Issue count created in that period&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This chart is most useful over a 90-day window. A stable horizontal line means your product quality is consistent. An upward trend after a release means the release introduced regressions. A downward trend is good news — though confirm it's not just a drop in reporting.&lt;/p&gt;

&lt;p&gt;If your team doesn't use a consistent label for customer-reported issues, this is the right time to establish one. The reporting value is significant.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chart 3 — Feature vs. Bug Ratio in the Backlog
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The question:&lt;/strong&gt; Is the backlog dominated by one type of work?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chart type: Pie or donut&lt;/li&gt;
&lt;li&gt;Filter: Open issues in the project&lt;/li&gt;
&lt;li&gt;Group by: Issue type&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a product team, the ideal ratio depends on the product maturity stage. A new product might be 80% features and 20% bugs. A mature product with a large install base might be 50/50. What you're watching for is a trend — if the bug proportion grows every quarter, quality investment is falling behind.&lt;/p&gt;

&lt;p&gt;This is also useful for product strategy conversations: when engineering says they need a "bug bash sprint," this chart gives you the data to support (or challenge) the request.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chart 4 — Backlog by Priority
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The question:&lt;/strong&gt; How much of the backlog is urgent?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chart type: Bar (horizontal)&lt;/li&gt;
&lt;li&gt;Filter: Open issues in backlog&lt;/li&gt;
&lt;li&gt;Group by: Priority&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A priority bar chart shows how the backlog breaks down by Critical, High, Medium, and Low. The ratio matters: a backlog that's 30% Critical and 40% High is telling you that your priority labels have inflated to the point of meaninglessness, or that there's genuinely too much urgent work and the team can't keep up.&lt;/p&gt;

&lt;p&gt;Review this chart before each quarterly planning cycle. If the High bar keeps growing despite the team working on High-priority issues, capacity is mismatched with demand.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chart 5 — Completed Work by Area
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The question:&lt;/strong&gt; What shipped this quarter, and in which product areas?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chart type: Bar&lt;/li&gt;
&lt;li&gt;Filter: &lt;code&gt;status = Done AND updated &amp;gt;= -90d&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Group by: Label (product area labels) or Component&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This chart is a retrospective view of where the team's output went. If you have labels for product areas ("auth," "billing," "reporting," "mobile"), a bar chart of completed issues by label shows what got attention. It's a useful starting point for "was this the quarter we said we'd focus on X?" conversations.&lt;/p&gt;

&lt;p&gt;Also useful for release notes compilation — filter to the release's fixVersion and group by issue type to see what categories of work shipped in that release.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting Up the PM Dashboard
&lt;/h2&gt;

&lt;p&gt;Create a dedicated Jira dashboard for product management. Don't share the sprint team's dashboard — the audiences and refresh cadences are different.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended layout — three columns:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Left column&lt;/th&gt;
&lt;th&gt;Center column&lt;/th&gt;
&lt;th&gt;Right column&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Release progress (bar)&lt;/td&gt;
&lt;td&gt;Customer bug trend (line)&lt;/td&gt;
&lt;td&gt;Backlog by priority (bar)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feature vs. bug ratio (pie)&lt;/td&gt;
&lt;td&gt;Completed by area (bar)&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(empty or a filter results table)&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Add a date range selector at the top if Charts for Jira supports a shared filter — change the range and both time-based charts update together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Share it:&lt;/strong&gt; Add the Confluence team, the engineering manager, and any design leads as viewers. A shared dashboard replaces the "can you pull the Jira report for the leadership update?" request with a link they can check themselves.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Good Jira Reporting Looks Like
&lt;/h2&gt;

&lt;p&gt;The sign that your dashboard is working: you open it in a meeting, look at it for 30 seconds, and can answer questions from it without typing a single JQL query. If you're still exporting to spreadsheet to get the answer you need, the dashboard isn't answering the right questions yet.&lt;/p&gt;

&lt;p&gt;Start with the release progress chart and the bug trend. Those two alone are more valuable than most Jira dashboards that have eight gadgets.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://marketplace.atlassian.com/apps/842672747/charts-reports-and-graphs-for-jira-dashboard?hosting=cloud&amp;amp;tab=overview" rel="noopener noreferrer"&gt;Install Charts for Jira Dashboard →&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Add a Cover Page to Confluence PDF Exports</title>
      <dc:creator>Yamuno</dc:creator>
      <pubDate>Wed, 08 Jul 2026 10:21:04 +0000</pubDate>
      <link>https://dev.to/yamuno-software/how-to-add-a-cover-page-to-confluence-pdf-exports-8dc</link>
      <guid>https://dev.to/yamuno-software/how-to-add-a-cover-page-to-confluence-pdf-exports-8dc</guid>
      <description>&lt;h1&gt;
  
  
  How to Add a Cover Page to Confluence PDF Exports
&lt;/h1&gt;

&lt;p&gt;Confluence's built-in PDF export produces the page content and nothing else. No title page, no table of contents, no company logo — just the raw content starting at the top of page one. For internal drafts that's workable. For anything going to a client, a stakeholder, or an external auditor, a document that starts abruptly with content and no cover page looks unfinished.&lt;/p&gt;

&lt;p&gt;PDF Exporter for Confluence adds a cover page option with six built-in styles, full branding control, and a live preview so you can see exactly how the cover looks before exporting.&lt;/p&gt;

&lt;p&gt;This guide covers how to set it up.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Install &lt;a href="https://marketplace.atlassian.com/apps/726790413" rel="noopener noreferrer"&gt;PDF Exporter for Confluence&lt;/a&gt; from the Atlassian Marketplace. Cover page configuration is done through the template system, which requires Confluence admin access.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 — Open the Template Editor
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Confluence Settings&lt;/strong&gt; (gear icon, top-right)&lt;/li&gt;
&lt;li&gt;In the left sidebar, click &lt;strong&gt;PDF Exporter&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Templates&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Either create a &lt;strong&gt;New Template&lt;/strong&gt; or click the edit (pencil) icon on an existing one&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 2 — Enable the Cover Page
&lt;/h2&gt;

&lt;p&gt;In the template editor, find the &lt;strong&gt;Cover Page&lt;/strong&gt; section and toggle it to enabled.&lt;/p&gt;

&lt;p&gt;Once enabled, the cover page configuration expands to show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cover style selector&lt;/li&gt;
&lt;li&gt;Accent color picker&lt;/li&gt;
&lt;li&gt;Subtitle field&lt;/li&gt;
&lt;li&gt;Author field&lt;/li&gt;
&lt;li&gt;Logo upload&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;strong&gt;live preview&lt;/strong&gt; on the right side of the editor updates as you make changes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Choose a Cover Style
&lt;/h2&gt;

&lt;p&gt;Six built-in styles are available:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Style&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Classic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;General-purpose documents, internal wikis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Corporate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Client-facing deliverables, formal proposals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Modern&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Product documentation, technical guides&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executive&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Board reports, executive summaries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bold&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Internal team reports, product launches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Minimal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;When you only need the title with no decoration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Click through the styles in the selector — the preview updates immediately so you can compare them without saving.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommendation for client-facing documents:&lt;/strong&gt; Corporate or Executive. Both have a restrained, professional look that works across industries. Avoid Bold for external documents — it's visually strong but can feel informal in a business context.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4 — Set the Accent Color
&lt;/h2&gt;

&lt;p&gt;The accent color controls the decorative elements on the cover: the color bar in Corporate style, the accent line in Executive style, the overlay block in Modern style, and so on.&lt;/p&gt;

&lt;p&gt;Click the color field and enter your hex value. Use your company's primary brand color.&lt;/p&gt;

&lt;p&gt;If you don't have a specific brand color, &lt;code&gt;#1e40af&lt;/code&gt; (dark blue) or &lt;code&gt;#1d4ed8&lt;/code&gt; (medium blue) works well for most professional contexts. Avoid very light colors — they disappear against a white background on some cover styles.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5 — Add Your Logo
&lt;/h2&gt;

&lt;p&gt;Click &lt;strong&gt;Upload Logo&lt;/strong&gt; and select your company logo (PNG, JPG, or SVG). The logo appears on the cover page alongside the document title.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Logo tips:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a horizontal logo variant if available — it fits better in most cover layouts&lt;/li&gt;
&lt;li&gt;PNG with a transparent background looks cleanest against the cover page background&lt;/li&gt;
&lt;li&gt;SVG scales perfectly at any size&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The logo is stored per template, so you upload it once and it appears on every export using this template.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6 — Configure Subtitle and Author
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Subtitle:&lt;/strong&gt; Optional text displayed below the document title. Use this for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Version numbers ("Version 2.3 — April 2026")&lt;/li&gt;
&lt;li&gt;Confidentiality notice ("Confidential — Not for External Distribution")&lt;/li&gt;
&lt;li&gt;Document type ("Technical Specification")&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Optional name displayed on the cover. For team-produced documents, use a team or department name ("Solutions Engineering," "Product Team") rather than an individual's name — it ages better and is more appropriate for documents that will be revised over time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7 — Save and Test
&lt;/h2&gt;

&lt;p&gt;Click &lt;strong&gt;Save&lt;/strong&gt;. The template is now available to all users on the instance.&lt;/p&gt;

&lt;p&gt;To test it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open any Confluence page&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;•••&lt;/strong&gt; → &lt;strong&gt;Export to PDF&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select your template from the dropdown&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Preview&lt;/strong&gt; (don't export yet — preview first)&lt;/li&gt;
&lt;li&gt;Check the cover page in the preview modal&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The preview shows the actual cover with your logo, accent color, and the Confluence page title as the document title. If anything looks off — logo too large, color doesn't match, subtitle missing — go back to the template and adjust.&lt;/p&gt;




&lt;h2&gt;
  
  
  How the Cover Page Interacts with the Rest of the PDF
&lt;/h2&gt;

&lt;p&gt;The cover page is always the first page. It does not count in page numbering — if you have page numbers enabled, they start from "1" on the first content page after the cover.&lt;/p&gt;

&lt;p&gt;If you also have a table of contents enabled, it appears after the cover page and before the content — the standard structure for a professional document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Cover Page]
[Table of Contents]  ← if enabled
[Content Pages]      ← page numbers start here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Exporting Without a Cover Page (When Needed)
&lt;/h2&gt;

&lt;p&gt;Sometimes you want a clean export without a cover — a raw content dump for internal review, or a quick single-page export that doesn't need a title page.&lt;/p&gt;

&lt;p&gt;The easiest approach is to keep a second "No Cover" template (or use the built-in Default template) for these cases. Users select the right template at export time based on what the document needs.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://marketplace.atlassian.com/apps/726790413" rel="noopener noreferrer"&gt;Install PDF Exporter for Confluence →&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/docs/pdf-exporter-for-confluence/features/cover-page"&gt;Read the documentation →&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Migrate from Notion to Confluence (Step-by-Step Guide)</title>
      <dc:creator>Yamuno</dc:creator>
      <pubDate>Fri, 03 Jul 2026 10:38:34 +0000</pubDate>
      <link>https://dev.to/yamuno-software/how-to-migrate-from-notion-to-confluence-step-by-step-guide-22l9</link>
      <guid>https://dev.to/yamuno-software/how-to-migrate-from-notion-to-confluence-step-by-step-guide-22l9</guid>
      <description>&lt;h1&gt;
  
  
  How to Migrate from Notion to Confluence
&lt;/h1&gt;

&lt;p&gt;Teams migrate from Notion to Confluence for different reasons — Atlassian ecosystem consolidation, enterprise SSO requirements, tighter Jira integration, or simply an organizational decision after a company merger. Whatever the reason, the migration path is more practical than it looks.&lt;/p&gt;

&lt;p&gt;Notion exports your content as markdown (or HTML). Confluence can import markdown. The gap between those two facts is what this guide covers: what the export gives you, what needs cleanup, and how to get everything into Confluence cleanly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 — Export Your Notion Workspace to Markdown
&lt;/h2&gt;

&lt;p&gt;In Notion:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;Settings &amp;amp; Members&lt;/strong&gt; → &lt;strong&gt;Settings&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Export all workspace content&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Markdown &amp;amp; CSV&lt;/strong&gt; as the export format&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;Include subpages&lt;/strong&gt; and &lt;strong&gt;Create folders for subpages&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Export&lt;/strong&gt; and download the ZIP&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The export produces a ZIP with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One &lt;code&gt;.md&lt;/code&gt; file per Notion page&lt;/li&gt;
&lt;li&gt;Subpages nested in folders matching the page hierarchy&lt;/li&gt;
&lt;li&gt;Images saved as local files (usually in a folder alongside each page)&lt;/li&gt;
&lt;li&gt;Database tables exported as &lt;code&gt;.csv&lt;/code&gt; files&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 2 — Understand What Transfers Well and What Doesn't
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Transfers cleanly:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text content, headings, paragraphs&lt;/li&gt;
&lt;li&gt;Bold, italic, inline code&lt;/li&gt;
&lt;li&gt;Bulleted and numbered lists&lt;/li&gt;
&lt;li&gt;Code blocks with language tags&lt;/li&gt;
&lt;li&gt;Images (as embedded files)&lt;/li&gt;
&lt;li&gt;Basic tables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Needs manual attention:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Notion databases&lt;/strong&gt; — exported as CSV, not as Confluence pages. Plan to recreate these as Confluence tables or use a Jira integration for structured data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Toggle blocks&lt;/strong&gt; — exported as regular text; the expand/collapse behavior is lost&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Notion-specific embeds&lt;/strong&gt; (YouTube, Figma, etc.) — exported as plain URLs, not embedded. You'll need to re-embed them in Confluence&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linked databases and relations&lt;/strong&gt; — not preserved in markdown export&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comments and mentions&lt;/strong&gt; — not included in the export&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a large workspace, do a test export and import of a small section first to understand what the output looks like for your specific content before committing to a full migration.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Clean Up the Exported Markdown
&lt;/h2&gt;

&lt;p&gt;Before importing, a few cleanup steps save time:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remove Notion IDs from filenames.&lt;/strong&gt; Notion appends a unique ID to every file and folder name (e.g., &lt;code&gt;Engineering Wiki a3f2c1b4d5e6.md&lt;/code&gt;). You can strip these with a script or a bulk rename tool. The Markdown Importer uses the filename as the Confluence page title, so cleaner names give you cleaner page titles.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# macOS/Linux — remove Notion IDs from .md filenames&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;f &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.md&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nv"&gt;newname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/ [a-f0-9]\{32\}\.md$/.md/'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$newname&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;mv&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$newname&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Convert CSV databases to markdown tables.&lt;/strong&gt; For Notion databases that you want in Confluence as pages (not Jira issues), convert the CSV to a markdown table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Quick CSV to markdown table conversion (Python)&lt;/span&gt;
python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
rows = list(csv.reader(open(sys.argv[1])))
print('| ' + ' | '.join(rows[0]) + ' |')
print('| ' + ' | '.join(['---'] * len(rows[0])) + ' |')
for row in rows[1:]:
    print('| ' + ' | '.join(row) + ' |')
"&lt;/span&gt; your-database.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Organize the folder structure.&lt;/strong&gt; Notion's export mirrors its page hierarchy as nested folders. Review the structure and reorganize if needed — the folder structure becomes the Confluence page hierarchy.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4 — Import into Confluence
&lt;/h2&gt;

&lt;p&gt;Install &lt;a href="https://marketplace.atlassian.com/apps/1228589694" rel="noopener noreferrer"&gt;Markdown Importer for Confluence&lt;/a&gt; from the Atlassian Marketplace.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For a small migration (up to 20–30 pages):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the target Confluence page (where the imported pages should live)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;•••&lt;/strong&gt; → &lt;strong&gt;Markdown Importer &amp;amp; Exporter&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select your cleaned-up markdown files or the ZIP archive&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;Page Hierarchy&lt;/strong&gt; to preserve folder structure as Confluence parent/child pages&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Import&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;For a large migration:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the ZIP upload option. Zip your cleaned-up Notion export folder (after stripping IDs and reorganizing) and upload it as a single archive. The importer processes the entire folder tree and creates the Confluence page hierarchy in one operation.&lt;/p&gt;

&lt;p&gt;If you're migrating multiple Notion workspaces or sections to different Confluence spaces, you can target different parent pages and spaces in separate import operations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5 — Handle Images
&lt;/h2&gt;

&lt;p&gt;Notion's markdown export embeds images as relative file paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;![&lt;/span&gt;&lt;span class="nv"&gt;Screenshot&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;./Screenshot_2025-03-14.png&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Markdown Importer reads the ZIP archive and uploads images as Confluence attachments, replacing the relative paths with Confluence attachment references automatically. This works when you import via ZIP — the images need to be inside the ZIP alongside the markdown files.&lt;/p&gt;

&lt;p&gt;If you're importing individual &lt;code&gt;.md&lt;/code&gt; files without a ZIP, images won't transfer automatically — you'll need to upload them to Confluence and update the image references manually.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6 — Post-Import Cleanup
&lt;/h2&gt;

&lt;p&gt;After the import, walk through the imported pages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check page titles.&lt;/strong&gt; The importer uses filenames as titles. If you missed some Notion IDs in the cleanup step, some pages will have IDs in their titles — rename them in Confluence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Re-embed external content.&lt;/strong&gt; Notion embeds for YouTube, Figma, Loom, or other services come through as plain URLs. Add Confluence macros or HTML Macro embeds to restore the embedded experience where it matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Review tables.&lt;/strong&gt; Notion tables with select, multi-select, or date columns export as text — the structured data type is lost. Verify these look reasonable in Confluence or recreate them using Confluence's table macro.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update internal links.&lt;/strong&gt; Links between Notion pages are relative paths in the export and may not resolve correctly after import. Run a search in Confluence for &lt;code&gt;notion.so&lt;/code&gt; URLs to find any that were hardcoded, and update them to Confluence page links.&lt;/p&gt;




&lt;h2&gt;
  
  
  What to Expect at Scale
&lt;/h2&gt;

&lt;p&gt;For a workspace with 200–500 pages, the full migration — export, cleanup, import — typically takes a day of dedicated effort. Larger workspaces benefit from dividing the work by Notion workspace section and importing incrementally rather than all at once.&lt;/p&gt;

&lt;p&gt;The most time-consuming part is usually the post-import cleanup: reviewing imported pages, fixing database content, and re-embedding media. Budget more time for this than for the import itself.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://marketplace.atlassian.com/apps/1228589694" rel="noopener noreferrer"&gt;Install Markdown Importer for Confluence →&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/docs/markdown-importer-for-confluence"&gt;Read the documentation →&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Track Jira Issues with Charts and Graphs</title>
      <dc:creator>Yamuno</dc:creator>
      <pubDate>Tue, 30 Jun 2026 11:11:57 +0000</pubDate>
      <link>https://dev.to/yamuno-software/how-to-track-jira-issues-with-charts-and-graphs-1nhf</link>
      <guid>https://dev.to/yamuno-software/how-to-track-jira-issues-with-charts-and-graphs-1nhf</guid>
      <description>&lt;h1&gt;
  
  
  How to Track Jira Issues with Charts and Graphs
&lt;/h1&gt;

&lt;p&gt;Jira stores detailed data about every issue — status, assignee, priority, type, labels, sprint, creation date, resolution date. The challenge isn't getting the data into Jira. It's getting anything useful out of it without building a spreadsheet report from scratch every week.&lt;/p&gt;

&lt;p&gt;This guide covers the most practical chart setups for tracking Jira issues — what to visualize, how to configure it, and what to look for in the output.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://marketplace.atlassian.com/apps/842672747/charts-reports-and-graphs-for-jira-dashboard?hosting=cloud&amp;amp;tab=overview" rel="noopener noreferrer"&gt;Charts - Reports and Graphs for Jira Dashboard&lt;/a&gt; adds chart gadgets to Jira dashboards. Install it from the Atlassian Marketplace, then add a gadget to any Jira dashboard by clicking &lt;strong&gt;Add gadget → Charts for Jira Dashboard&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each gadget is configured independently — choose the chart type, data source (project, JQL query, or label filter), grouping, and visual options.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Status Distribution — Where Is Everything Right Now?
&lt;/h2&gt;

&lt;p&gt;The most immediate question for any sprint or project is: how many issues are in each status?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chart type:&lt;/strong&gt; Bar (horizontal)&lt;br&gt;
&lt;strong&gt;Group by:&lt;/strong&gt; Status&lt;br&gt;
&lt;strong&gt;Filter:&lt;/strong&gt; Current sprint or open issues in the project&lt;/p&gt;

&lt;p&gt;A horizontal bar chart with one bar per status — To Do, In Progress, In Review, Done — gives you the snapshot at a glance. When "In Review" is twice as wide as "In Progress," you know reviews are backing up.&lt;/p&gt;

&lt;p&gt;For a kanban team without sprints, filter to "all open issues" and group by status. The relative bar lengths show your work in progress distribution and immediately reveal if one column is accumulating more than expected.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Assignee Workload — Is Work Distributed Evenly?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Chart type:&lt;/strong&gt; Bar (vertical or horizontal)&lt;br&gt;
&lt;strong&gt;Group by:&lt;/strong&gt; Assignee&lt;br&gt;
&lt;strong&gt;Filter:&lt;/strong&gt; Open issues in current sprint or project&lt;/p&gt;

&lt;p&gt;This chart answers the question that comes up in every sprint planning meeting: is the work actually balanced? One bar per team member, height representing open issue count.&lt;/p&gt;

&lt;p&gt;The useful insight isn't just the current distribution — it's the pattern over multiple sprints. If the same one or two people consistently have the highest bars, that's a structural problem worth addressing, not a one-sprint anomaly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Refinement:&lt;/strong&gt; Add a second dataset for "In Progress" issues only (by adding a JQL filter &lt;code&gt;status = "In Progress"&lt;/code&gt;). Now you can see not just who has the most assigned, but who is actively working on the most issues simultaneously — which is a better signal for overload.&lt;/p&gt;


&lt;h2&gt;
  
  
  3. Priority Breakdown — Where Are the Critical Issues?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Chart type:&lt;/strong&gt; Pie or bar&lt;br&gt;
&lt;strong&gt;Group by:&lt;/strong&gt; Priority&lt;br&gt;
&lt;strong&gt;Filter:&lt;/strong&gt; Open issues in the project&lt;/p&gt;

&lt;p&gt;A priority pie chart shows the proportion of Critical, High, Medium, and Low issues in your backlog. This is most useful for bug tracking and escalation management.&lt;/p&gt;

&lt;p&gt;If you're watching this chart over time (check it at the start of each sprint), a growing "Critical" slice is an early warning sign that something in your triage process or product isn't working. A shrinking "High" slice alongside increasing "Critical" might mean labels are being inflated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Practical use:&lt;/strong&gt; Share this chart in your sprint retrospective. If the team sees that 40% of issues tagged Critical are consistently de-prioritized, the label is losing meaning — worth a conversation.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. Issue Type Distribution — What Kind of Work Are We Doing?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Chart type:&lt;/strong&gt; Pie or donut&lt;br&gt;
&lt;strong&gt;Group by:&lt;/strong&gt; Issue type&lt;br&gt;
&lt;strong&gt;Filter:&lt;/strong&gt; Issues created in the last 30 days, or current sprint&lt;/p&gt;

&lt;p&gt;Jira issue types (Bug, Feature, Task, Story, Spike, Tech Debt) tell you the composition of what the team is actually working on. If your roadmap says "feature development sprint" but the chart shows 60% bugs, you have a planning alignment issue.&lt;/p&gt;

&lt;p&gt;This chart is most useful at the project or team level, not the sprint level — one sprint's composition can be an anomaly. The 30-day or 90-day view shows the actual pattern.&lt;/p&gt;


&lt;h2&gt;
  
  
  5. Sprint Progress — Are We on Track to Complete?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Chart type:&lt;/strong&gt; Bar (grouped or stacked)&lt;br&gt;
&lt;strong&gt;Group by:&lt;/strong&gt; Status&lt;br&gt;
&lt;strong&gt;Filter:&lt;/strong&gt; Current sprint&lt;/p&gt;

&lt;p&gt;A grouped bar chart with two bars — "Completed" and "Remaining" — is a straightforward sprint progress view. Set it up at sprint start and check it mid-sprint. The relative bar heights tell you immediately whether you're ahead, on track, or behind.&lt;/p&gt;

&lt;p&gt;For a more nuanced view, use a stacked bar grouped by status: a single bar per sprint with segments for To Do, In Progress, In Review, and Done. This shows not just completed vs. remaining, but where the remaining work is sitting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JQL for current sprint:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;YOURPROJECT&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;sprint&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;openSprints&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Label-Based Tracking — Custom Dimensions
&lt;/h2&gt;

&lt;p&gt;Jira labels are underused for reporting. If your team uses consistent labels — "customer-request," "regression," "tech-debt," "blocked" — you can build charts that filter to those labels.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A bar chart filtered to &lt;code&gt;label = "customer-request"&lt;/code&gt; grouped by status shows how many customer-requested issues are open vs. in progress vs. done. This is the chart that goes in a customer success update without you needing to manually compile a list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A count of &lt;code&gt;label = "blocked"&lt;/code&gt; issues over time (if you're logging blocked state via label) reveals whether your impediment rate is stable or trending up.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building a Dashboard Around These Charts
&lt;/h2&gt;

&lt;p&gt;A practical dashboard for a sprint team: three gadgets on one board.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gadget&lt;/th&gt;
&lt;th&gt;Chart&lt;/th&gt;
&lt;th&gt;Data&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Status distribution (bar)&lt;/td&gt;
&lt;td&gt;Current sprint issues&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Assignee workload (bar)&lt;/td&gt;
&lt;td&gt;Open issues, current sprint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Priority breakdown (pie)&lt;/td&gt;
&lt;td&gt;Open bugs in the project&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That's enough to run a 15-minute sprint check-in without opening any Jira filters. Everyone looks at the same charts, asks questions from the same data, and the meeting moves faster.&lt;/p&gt;

&lt;p&gt;Add a date filter at the top of the dashboard and make it the single control that drives all three gadgets. When stakeholders ask "what did we do last month," you change the date range and the answer is visible immediately.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://marketplace.atlassian.com/apps/842672747/charts-reports-and-graphs-for-jira-dashboard?hosting=cloud&amp;amp;tab=overview" rel="noopener noreferrer"&gt;Install Charts for Jira Dashboard →&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Exporting Confluence Documentation for Clients: A Practical Guide</title>
      <dc:creator>Yamuno</dc:creator>
      <pubDate>Wed, 24 Jun 2026 10:52:41 +0000</pubDate>
      <link>https://dev.to/yamuno-software/exporting-confluence-documentation-for-clients-a-practical-guide-4lce</link>
      <guid>https://dev.to/yamuno-software/exporting-confluence-documentation-for-clients-a-practical-guide-4lce</guid>
      <description>&lt;h1&gt;
  
  
  Exporting Confluence Documentation for Clients
&lt;/h1&gt;

&lt;p&gt;Most Confluence documentation is written for internal audiences — people who have access to the instance and can navigate the space directly. But plenty of documentation ends up going to people who don't have Confluence access: clients receiving a project handover, stakeholders reviewing a technical spec, partners getting onboarded, or auditors requesting documentation exports.&lt;/p&gt;

&lt;p&gt;Confluence's built-in PDF export exists, but it produces bare output: no cover page, no custom headers, no watermarks, and no way to save a consistent format so the next export looks like this one. For internal drafts that's fine. For a client deliverable, it's not.&lt;/p&gt;

&lt;p&gt;This guide covers how to export professional, consistently formatted PDFs from Confluence for external distribution using &lt;a href="https://marketplace.atlassian.com/apps/726790413" rel="noopener noreferrer"&gt;PDF Exporter for Confluence&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Setup: Admin Creates a Template, Users Apply It
&lt;/h2&gt;

&lt;p&gt;The key to consistent output across a team is templates. An admin creates a "Client Deliverable" template once in Confluence Settings. After that, any team member exporting for a client selects that template and gets the same cover page, header, and formatting — without touching any configuration themselves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Admin step (one time):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Confluence Settings → PDF Exporter → Templates → New Template&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Name it "Client Deliverable"&lt;/li&gt;
&lt;li&gt;Configure it as described below&lt;/li&gt;
&lt;li&gt;Save&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;User step (every export):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the Confluence page or parent page to export&lt;/li&gt;
&lt;li&gt;••• → Export to PDF&lt;/li&gt;
&lt;li&gt;Select "Client Deliverable" template&lt;/li&gt;
&lt;li&gt;Choose scope (single page, page tree, or space)&lt;/li&gt;
&lt;li&gt;Export and download&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Recommended Template Settings for Client-Facing PDFs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Cover Page
&lt;/h3&gt;

&lt;p&gt;Enable the cover page. For client deliverables, &lt;strong&gt;Corporate&lt;/strong&gt; or &lt;strong&gt;Executive&lt;/strong&gt; style works best:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Corporate&lt;/strong&gt; — left-aligned with a solid color accent bar, professional and structured&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Executive&lt;/strong&gt; — minimal with a thin accent line, suits formal proposals and executive-level documents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Set the accent color to your company's primary brand color (hex). Upload your company logo. Add a subtitle field — "Prepared for [Client Name]" or "Confidential — [Date]" — as a manual step per export.&lt;/p&gt;

&lt;h3&gt;
  
  
  Header
&lt;/h3&gt;

&lt;p&gt;Enable the header with your company name or document series title, centered. This appears on every content page and reinforces the source of the document even when pages are printed individually.&lt;/p&gt;

&lt;h3&gt;
  
  
  Footer
&lt;/h3&gt;

&lt;p&gt;Add page numbers (right-aligned) and a confidentiality notice (left-aligned):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Confidential — [Company Name]                                       Page 1 of 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This combination is standard for client-facing documentation in most professional services contexts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Watermark
&lt;/h3&gt;

&lt;p&gt;For documents that are drafts or under review, enable the watermark with "DRAFT" at 0.15 opacity. Remove it from the template (or create a separate "Client Draft" template) when the document is final.&lt;/p&gt;

&lt;h3&gt;
  
  
  Table of Contents
&lt;/h3&gt;

&lt;p&gt;Enable for any multi-page export. Set depth to 2 (H1 and H2). This is especially important for handover packages and technical specs where clients need to navigate to specific sections.&lt;/p&gt;

&lt;h3&gt;
  
  
  Page Breaks
&lt;/h3&gt;

&lt;p&gt;Enable "Break before H1" so each major section starts on a new page. For longer documents, also enable "Break before H2."&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Export Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Project Handover Package
&lt;/h3&gt;

&lt;p&gt;A handover package typically spans multiple Confluence pages — architecture overview, runbooks, configuration guides, contact lists. Export the entire section as a page tree:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to the parent page of the handover section&lt;/li&gt;
&lt;li&gt;••• → Export to PDF&lt;/li&gt;
&lt;li&gt;Select the page tree — uncheck any internal-only pages you don't want in the client copy&lt;/li&gt;
&lt;li&gt;Select "Client Deliverable" template&lt;/li&gt;
&lt;li&gt;Export — downloads as a ZIP with each section as a separate PDF&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Alternatively, if you want a single combined PDF, check all pages under one parent. The exporter bundles them in page tree order.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Specification
&lt;/h3&gt;

&lt;p&gt;A single-page export is appropriate for a spec document or proposal:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the spec page&lt;/li&gt;
&lt;li&gt;••• → Export to PDF&lt;/li&gt;
&lt;li&gt;Select "Client Deliverable" template&lt;/li&gt;
&lt;li&gt;Export — single PDF download&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the spec has an H1-level structure with multiple major sections, the table of contents and page breaks make it easy to navigate without Confluence access.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compliance Documentation Export
&lt;/h3&gt;

&lt;p&gt;For regulatory submissions or audit requests, use a separate "Compliance Archive" template with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Executive&lt;/strong&gt; cover style&lt;/li&gt;
&lt;li&gt;Watermark: "ARCHIVED" or "CONFIDENTIAL" at 0.2 opacity&lt;/li&gt;
&lt;li&gt;Footer: department name and export date&lt;/li&gt;
&lt;li&gt;No table of contents unless required by the submission format&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create this template with watermark enabled by default so it's never accidentally omitted on a compliance export.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recurring Status Report
&lt;/h3&gt;

&lt;p&gt;If you export a weekly or monthly status report page to send to a client, the template eliminates the manual formatting step entirely. Update the Confluence page with new content, export with the "Client Deliverable" template, and the output is ready to send. The cover page, header, and formatting are consistent every time without any effort.&lt;/p&gt;




&lt;h2&gt;
  
  
  Space Export for Full Documentation Sets
&lt;/h2&gt;

&lt;p&gt;For clients receiving a complete documentation set (e.g., a full product documentation space), use the space export:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;From the global Apps menu, open &lt;strong&gt;PDF Exporter for Confluence&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The page tree for the current space is displayed&lt;/li&gt;
&lt;li&gt;Select all pages or deselect internal-only pages&lt;/li&gt;
&lt;li&gt;Apply the template&lt;/li&gt;
&lt;li&gt;Export — downloads as a ZIP of PDFs matching the space hierarchy&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is useful for project completion handovers, vendor certifications, or any situation where the client needs a complete copy of a documentation space they won't have ongoing access to.&lt;/p&gt;




&lt;h2&gt;
  
  
  Before You Send
&lt;/h2&gt;

&lt;p&gt;Before the PDF goes to the client:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use the &lt;strong&gt;Preview&lt;/strong&gt; option in the exporter to verify the cover page, header, and first few pages look correct&lt;/li&gt;
&lt;li&gt;Check that the subtitle on the cover page reflects the correct client name or document version&lt;/li&gt;
&lt;li&gt;Confirm the watermark is absent if the document is final (or present if it's still a draft)&lt;/li&gt;
&lt;li&gt;Open the downloaded PDF to verify the table of contents links work and the page numbering is correct&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The preview step takes 30 seconds and catches the issues — wrong accent color, missing logo, leftover watermark — that would otherwise be visible to the client.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://marketplace.atlassian.com/apps/726790413" rel="noopener noreferrer"&gt;Install PDF Exporter for Confluence →&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/docs/pdf-exporter-for-confluence"&gt;Read the documentation →&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Manage Confluence Attachments at Scale</title>
      <dc:creator>Yamuno</dc:creator>
      <pubDate>Sat, 20 Jun 2026 10:34:44 +0000</pubDate>
      <link>https://dev.to/yamuno-software/how-to-manage-confluence-attachments-at-scale-2i6g</link>
      <guid>https://dev.to/yamuno-software/how-to-manage-confluence-attachments-at-scale-2i6g</guid>
      <description>&lt;h1&gt;
  
  
  How to Manage Confluence Attachments at Scale
&lt;/h1&gt;

&lt;p&gt;Confluence storage fills up in a predictable way. Teams upload screenshots, export files, and old versions of diagrams. Pages get reorganized or deleted. The attachments stay. After a year or two, a significant portion of your Confluence storage is files that are no longer referenced by any page — orphaned attachments that cost storage budget without serving any purpose.&lt;/p&gt;

&lt;p&gt;Cleaning this up manually is impractical at any scale. This guide covers how to audit and manage Confluence attachments systematically using &lt;a href="https://marketplace.atlassian.com/apps/1228602938" rel="noopener noreferrer"&gt;Advanced Attachment Manager for Confluence&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Problem: Unused Attachments
&lt;/h2&gt;

&lt;p&gt;An unused attachment is a file that was uploaded to Confluence but is no longer referenced anywhere in page content. This happens when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A page is deleted but its attachments remain&lt;/li&gt;
&lt;li&gt;An image is uploaded, replaced by a newer version, and the old version is left&lt;/li&gt;
&lt;li&gt;A file is attached to a page during a draft but never embedded in the final content&lt;/li&gt;
&lt;li&gt;Content is migrated from one space to another and the source attachments are left behind&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Confluence's native attachment view shows you files per page. It doesn't have a cross-space view, doesn't flag unused files, and doesn't support bulk operations. Advanced Attachment Manager does.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 — Find Unused Attachments
&lt;/h2&gt;

&lt;p&gt;Open Advanced Attachment Manager from the Confluence global navigation: &lt;strong&gt;Apps → Advanced Attachment Manager&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The first filter to apply: &lt;strong&gt;Usage Status → Unused&lt;/strong&gt;. This surfaces every attachment in the selected scope (page, space, or instance-wide) that isn't currently referenced by any page content.&lt;/p&gt;

&lt;p&gt;For most Confluence instances that haven't been audited recently, this list is longer than expected. Sort by &lt;strong&gt;File Size (descending)&lt;/strong&gt; to see the biggest storage consumers first — a handful of large video files or exported PDFs often account for a disproportionate share.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2 — Filter Down to What's Safe to Delete
&lt;/h2&gt;

&lt;p&gt;Not every unused attachment should be deleted. Some are referenced in archived pages. Some are version history that someone may need to reference. Apply additional filters to narrow to what's clearly safe:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filter by file type:&lt;/strong&gt; Images and exported PDFs are the most common orphans. Filter to &lt;code&gt;Images&lt;/code&gt; or &lt;code&gt;Documents&lt;/code&gt; to work through the most common cases first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filter by upload date:&lt;/strong&gt; Files uploaded more than 12 months ago and never used are strong candidates for deletion. Set the upload date range to filter out recent uploads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filter by uploader:&lt;/strong&gt; If a departed team member uploaded most of the unused files, filtering by uploader gives you a focused list to review.&lt;/p&gt;

&lt;p&gt;Use shift-click and ctrl/cmd-click to select individual files, or &lt;strong&gt;Select All&lt;/strong&gt; after applying filters to select the entire filtered result set.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Download Before Deleting (When Uncertain)
&lt;/h2&gt;

&lt;p&gt;For any batch where you're not 100% confident, use &lt;strong&gt;Bulk Download&lt;/strong&gt; before deleting. This downloads all selected files as a ZIP archive to your local machine.&lt;/p&gt;

&lt;p&gt;Bulk Download is also useful for migration and archival purposes — before decommissioning a Confluence space, download all attachments to preserve them outside Confluence.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4 — Bulk Delete
&lt;/h2&gt;

&lt;p&gt;With the files selected:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Delete Selected&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Review the confirmation dialog — it shows the count and total size being freed&lt;/li&gt;
&lt;li&gt;Confirm the deletion&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Deletions are logged to the audit trail immediately. If you delete something that turns out to be needed, check the audit log first to confirm what was removed, then check if it can be recovered from Confluence's trash.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5 — Review the Audit Log
&lt;/h2&gt;

&lt;p&gt;Every action taken in Advanced Attachment Manager — views, downloads, deletions — is recorded in the audit log. Access it from the app sidebar.&lt;/p&gt;

&lt;p&gt;The audit log shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Action type (deleted, downloaded, viewed)&lt;/li&gt;
&lt;li&gt;File name and size&lt;/li&gt;
&lt;li&gt;Space and page the file was attached to&lt;/li&gt;
&lt;li&gt;User who performed the action&lt;/li&gt;
&lt;li&gt;Timestamp&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is important for compliance-sensitive environments: you have a complete record of what was removed, by whom, and when.&lt;/p&gt;




&lt;h2&gt;
  
  
  Scheduling Regular Cleanups
&lt;/h2&gt;

&lt;p&gt;Attachment management is most effective as a recurring process rather than a one-time cleanup. A quarterly cadence works for most teams:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Filter to unused attachments uploaded more than 90 days ago&lt;/li&gt;
&lt;li&gt;Sort by size, work through the top 50 by size&lt;/li&gt;
&lt;li&gt;Bulk delete the clearly obsolete ones&lt;/li&gt;
&lt;li&gt;Download and archive anything uncertain&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After two or three cycles, the backlog of orphaned files is small enough that the quarterly review takes 15–20 minutes instead of hours.&lt;/p&gt;




&lt;h2&gt;
  
  
  Space-Level vs. Instance-Level Audits
&lt;/h2&gt;

&lt;p&gt;Advanced Attachment Manager supports two scopes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Space-level:&lt;/strong&gt; Scope the view to a specific Confluence space. Useful for space owners doing routine maintenance on their own space.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instance-level:&lt;/strong&gt; Confluence admins can view attachments across the entire instance. This is the right starting point for a storage audit — see total consumption by space, identify which spaces are the biggest consumers, and then drill into each one.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Note on Storage Recovery
&lt;/h2&gt;

&lt;p&gt;After bulk deletion, Confluence doesn't immediately reclaim storage — deleted files go to Confluence trash first. A Confluence admin needs to empty the trash to release the storage.&lt;/p&gt;

&lt;p&gt;Go to &lt;strong&gt;Confluence Administration → Trash → Empty Trash&lt;/strong&gt;. After emptying, the storage reduction is reflected in your instance's storage usage.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://marketplace.atlassian.com/apps/1228602938" rel="noopener noreferrer"&gt;Install Advanced Attachment Manager for Confluence →&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Embed Interactive Charts in Confluence with HTML Macro</title>
      <dc:creator>Yamuno</dc:creator>
      <pubDate>Tue, 16 Jun 2026 12:56:22 +0000</pubDate>
      <link>https://dev.to/yamuno-software/how-to-embed-interactive-charts-in-confluence-with-html-macro-4ai3</link>
      <guid>https://dev.to/yamuno-software/how-to-embed-interactive-charts-in-confluence-with-html-macro-4ai3</guid>
      <description>&lt;h1&gt;
  
  
  How to Embed Interactive Charts in Confluence with HTML Macro
&lt;/h1&gt;

&lt;p&gt;Confluence is where a lot of teams track project status, document KPIs, and share team metrics. But when it comes to actually visualizing that data, the options are limited. You can paste a static image (which goes stale), use a third-party integration (which requires a separate subscription), or accept that your Confluence page just won't have charts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.atlassian.com/apps/1670180315/html-macro-for-confluence-free?hosting=cloud&amp;amp;tab=overview" rel="noopener noreferrer"&gt;HTML Macro for Confluence&lt;/a&gt; opens a fourth option: embed Chart.js directly inside a Confluence page. The charts are interactive (hover for tooltips, click to toggle series), render instantly, and live alongside your documentation — no external service required.&lt;/p&gt;

&lt;p&gt;This guide covers four chart types with copy-paste code for each.&lt;/p&gt;




&lt;h2&gt;
  
  
  Before You Start
&lt;/h2&gt;

&lt;p&gt;Install &lt;a href="https://marketplace.atlassian.com/apps/1670180315/html-macro-for-confluence-free?hosting=cloud&amp;amp;tab=overview" rel="noopener noreferrer"&gt;HTML Macro for Confluence&lt;/a&gt; from the Atlassian Marketplace. It's free and runs on Atlassian Forge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security note:&lt;/strong&gt; The examples below load Chart.js from a CDN (&lt;code&gt;cdn.jsdelivr.net&lt;/code&gt;). Your Confluence admin needs to add that domain to the HTML Macro whitelist. Go to &lt;strong&gt;Confluence Settings → HTML Macro → Security Settings&lt;/strong&gt; and add &lt;code&gt;https://cdn.jsdelivr.net&lt;/code&gt; to the allowed domains.&lt;/p&gt;

&lt;p&gt;Once that's done, add the macro to any Confluence page (Insert → Macro → HTML Macro), paste the code, and use the live preview to verify it before saving.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bar Chart — Team Metrics or Sprint Data
&lt;/h2&gt;

&lt;p&gt;Good for: comparing values across categories — issues by status, story points per sprint, bugs per team member.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;canvas&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"barChart"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"700"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"350"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/chart.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;barChart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;To Do&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;In Progress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;In Review&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Done&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;datasets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Issues&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#94a3b8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#3b82f6&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f59e0b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#22c55e&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;responsive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Issue Status — Sprint 42&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;font&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;600&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#1e293b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;scales&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;beginAtZero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f1f5f9&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;ticks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#64748b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;ticks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#64748b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the &lt;code&gt;labels&lt;/code&gt; and &lt;code&gt;data&lt;/code&gt; arrays with your actual values. Each label maps to the corresponding data value by index.&lt;/p&gt;




&lt;h2&gt;
  
  
  Line Chart — Velocity Trend or Weekly Progress
&lt;/h2&gt;

&lt;p&gt;Good for: showing trends over time — sprint velocity, bug discovery rate, weekly active users, anything with a time axis.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;canvas&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"lineChart"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"700"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"350"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/chart.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lineChart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sprint 37&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sprint 38&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sprint 39&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sprint 40&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sprint 41&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sprint 42&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;datasets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Story Points Completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;38&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#6366f1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rgba(99, 102, 241, 0.08)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;borderWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;pointBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#6366f1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;pointRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;tension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;responsive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;top&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sprint Velocity — Last 6 Sprints&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;font&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;600&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#1e293b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;scales&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;beginAtZero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f1f5f9&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;ticks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#64748b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;ticks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#64748b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Pie Chart — Issue Type or Priority Distribution
&lt;/h2&gt;

&lt;p&gt;Good for: showing how a total is distributed — issue types, budget allocation, time spent by category. Keep it to five segments or fewer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;canvas&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"pieChart"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"500"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"400"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/chart.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pieChart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pie&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Feature&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Task&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tech Debt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Spike&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;datasets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ef4444&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#6366f1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#3b82f6&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f59e0b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#94a3b8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;borderWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;responsive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;right&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Open Issues by Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;font&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;600&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#1e293b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Doughnut Chart — Goal Progress or Completion Status
&lt;/h2&gt;

&lt;p&gt;Good for: showing a single metric against a target — sprint completion, budget consumed, onboarding progress.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position:relative; width:400px; margin:0 auto;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;canvas&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"doughnutChart"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"400"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"400"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); text-align:center; font-family:sans-serif;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:36px; font-weight:700; color:#1e293b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;72%&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size:13px; color:#64748b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Complete&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/chart.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;doughnutChart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;doughnut&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;datasets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#6366f1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f1f5f9&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;borderWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;cutout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;78%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;responsive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;tooltip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the &lt;code&gt;72&lt;/code&gt; and &lt;code&gt;28&lt;/code&gt; values (they must add to 100) and update the center label to match.&lt;/p&gt;




&lt;h2&gt;
  
  
  Multi-Dataset Line Chart — Compare Two Teams or Products
&lt;/h2&gt;

&lt;p&gt;When you want to compare two data series on the same time axis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;canvas&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"multiLineChart"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"700"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"350"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/chart.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;multiLineChart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Week 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Week 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Week 3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Week 4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Week 5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Week 6&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;datasets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Team Alpha&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="na"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#6366f1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;transparent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;borderWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;pointRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;tension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Team Beta&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="na"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#22c55e&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;transparent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;borderWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;pointRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;tension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;responsive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;top&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Weekly Issues Resolved&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;font&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;600&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#1e293b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;scales&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;beginAtZero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f1f5f9&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Tips for Production Use
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hard-code the data for now.&lt;/strong&gt; Chart.js in Confluence can't call your Jira API or database — the data lives in the HTML. If your metrics change weekly, treat the Confluence page as a weekly snapshot: update the arrays when you update the commentary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; attributes directly on &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;.&lt;/strong&gt; Don't rely on &lt;code&gt;responsive: true&lt;/code&gt; inside Confluence — the macro iframe has fixed dimensions and responsive sizing can behave unexpectedly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Each chart needs a unique &lt;code&gt;id&lt;/code&gt;.&lt;/strong&gt; If you put multiple charts on the same page, give each canvas a different id (&lt;code&gt;barChart&lt;/code&gt;, &lt;code&gt;lineChart&lt;/code&gt;, etc.) to avoid conflicts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test in the live preview before saving.&lt;/strong&gt; HTML Macro's side-by-side preview shows you exactly what Confluence page visitors will see — including CDN scripts loading.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Note on the CDN Whitelist
&lt;/h2&gt;

&lt;p&gt;Your admin needs to whitelist &lt;code&gt;https://cdn.jsdelivr.net&lt;/code&gt; in HTML Macro's security settings for the Chart.js scripts to load. If the charts appear blank, that's the most common cause. Check the browser console for a CSP error and confirm the domain is in the allowlist.&lt;/p&gt;

&lt;p&gt;For environments where all external CDNs are blocked, you can paste the minified Chart.js source directly into the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag — it's about 60KB minified, which is manageable.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://marketplace.atlassian.com/apps/1670180315/html-macro-for-confluence-free?hosting=cloud&amp;amp;tab=overview" rel="noopener noreferrer"&gt;Install HTML Macro for Confluence — free on the Atlassian Marketplace&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
