Mingcedar

Product: Mingcedar CONTROL

Page SDK: quick start | Mingcedar

Upload HTML to Screen Files and open it from a runtime menu. Runtime loads the SDK; no npm package or extra script is needed. Call ready() once and reuse api.

Published Updated

<div class="manual-doc-article manual-doc-article-section"><h2 id="custom-page-tutorial">Developer guide: Page SDK: quick start</h2>

Use the Page SDK to read Tags, write setpoints, and query alarms and trends. The HTML and Vue examples require project Tag codes and permission checks before publishing.

<div class="doc-card-list doc-tutorial">

<article class="doc-card">

<h3 id="custom-page-tutorial-item-1">How the SDK loads</h3>

<p>Upload HTML to Screen Files and open it from a runtime menu. Runtime loads the SDK; no npm package or extra script is needed. Call ready() once and reuse api.</p>

<div class="manual-code" data-code-language="javascript"><div class="manual-code-toolbar"><span>JavaScript</span><span class="manual-code-tools"><small>JavaScript</small><button type="button" data-copy-code data-copied="Copied" data-failed="Select and copy the code" aria-label="Copy code: JavaScript">Copy code</button><span class="manual-code-status" role="status"></span></span></div><pre tabindex="0" class="docs-code-block shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#005CC5">HQVISU_CUSTOM_PAGE</span><span style="color:#24292E">.</span><span style="color:#6F42C1">ready</span><span style="color:#24292E">().</span><span style="color:#6F42C1">then</span><span style="color:#24292E">(</span><span style="color:#D73A49">async</span><span style="color:#24292E"> (</span><span style="color:#E36209">api</span><span style="color:#24292E">) </span><span style="color:#D73A49">=></span><span style="color:#24292E"> {</span></span>

<span class="line"><span style="color:#6A737D"> // Use the examples below here. Reuse this api object.</span></span>

<span class="line"><span style="color:#24292E">}).</span><span style="color:#6F42C1">catch</span><span style="color:#24292E">(</span><span style="color:#E36209">error</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> console.</span><span style="color:#6F42C1">error</span><span style="color:#24292E">(error.message));</span></span></code></pre></div>

<p class="doc-step-result"><strong>Expected result</strong> In plain HTML, place the script at the end of body, after the page elements. Add selected snippets to the same async callback and reuse api. Standalone Vite servers, file://, and other sites do not provide this runtime.</p>

<ul class="doc-related-links">

<li><a href="/en/hqserver/manual/custom-page-sdk/#custom-page-sdk-item-4">loading options</a></li>

</ul>

</article>

<article class="doc-card">

<h3 id="sdk-expand">Declare the Tags your page uses</h3>

<p>Put this declaration in the entry HTML head. Replace &lt;device-code&gt;.&lt;tag-code&gt; with the actual full code. Use writableTags: [] for a read-only page. For Vue, put it in index.html.</p>

<div class="manual-code" data-code-language="html"><div class="manual-code-toolbar"><span>HTML</span><span class="manual-code-tools"><small>HTML</small><button type="button" data-copy-code data-copied="Copied" data-failed="Select and copy the code" aria-label="Copy code: HTML">Copy code</button><span class="manual-code-status" role="status"></span></span></div><pre tabindex="0" class="docs-code-block shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">script</span><span style="color:#24292E">>window.</span><span style="color:#005CC5">HQVISU_PAGE_META</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> { layoutMode: </span><span style="color:#032F62">"native"</span><span style="color:#24292E"> };&#x3C;/</span><span style="color:#22863A">script</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">script</span><span style="color:#6F42C1"> type</span><span style="color:#24292E">=</span><span style="color:#032F62">"application/json"</span><span style="color:#6F42C1"> id</span><span style="color:#24292E">=</span><span style="color:#032F62">"hqvisu-custom-page"</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">{</span></span>

<span class="line"><span style="color:#24292E"> "readableTags": ["&#x3C;device-code>.&#x3C;tag-code>"],</span></span>

<span class="line"><span style="color:#24292E"> "writableTags": ["&#x3C;device-code>.&#x3C;tag-code>"]</span></span>

<span class="line"><span style="color:#24292E">}</span></span>

<span class="line"><span style="color:#24292E">&#x3C;/</span><span style="color:#22863A">script</span><span style="color:#24292E">></span></span></code></pre></div>

<p class="doc-step-result"><strong>Expected result</strong> layoutMode: &quot;native&quot; lets plain HTML/Vue use a responsive viewport layout. readableTags declares reads; writableTags declares writes. A declaration does not grant control permissions to the account.</p>

</article>

<article class="doc-card">

<h3 id="custom-page-tutorial-item-4">Read a Tag</h3>

<p>Add &lt;output id=&quot;value&quot;&gt;&lt;/output&gt;. Read numbers with ReadTagDouble and use null for unavailable data. Use ReadTagInteger, ReadTagBoolean, or ReadTagString for other types.</p>

<div class="manual-code" data-code-language="javascript"><div class="manual-code-toolbar"><span>JavaScript</span><span class="manual-code-tools"><small>JavaScript</small><button type="button" data-copy-code data-copied="Copied" data-failed="Select and copy the code" aria-label="Copy code: JavaScript">Copy code</button><span class="manual-code-status" role="status"></span></span></div><pre tabindex="0" class="docs-code-block shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> value</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> api.</span><span style="color:#6F42C1">ReadTagDouble</span><span style="color:#24292E">(</span><span style="color:#032F62">"&#x3C;device-code>.&#x3C;tag-code>"</span><span style="color:#24292E">, </span><span style="color:#005CC5">null</span><span style="color:#24292E">);</span></span>

<span class="line"><span style="color:#24292E">document.</span><span style="color:#6F42C1">getElementById</span><span style="color:#24292E">(</span><span style="color:#032F62">"value"</span><span style="color:#24292E">).textContent </span><span style="color:#D73A49">=</span><span style="color:#24292E"> value </span><span style="color:#D73A49">??</span><span style="color:#032F62"> "—"</span><span style="color:#24292E">;</span></span></code></pre></div>

<p class="doc-step-result"><strong>Expected result</strong> The call synchronously reads the latest collected value without polling the PLC. Display null as “—”, not a real zero.</p>

</article>

<article class="doc-card">

<h3 id="sdk-first-value">Update when the value changes</h3>

<p>Add &lt;output id=&quot;value&quot;&gt;&lt;/output&gt; to the HTML and use subscribe to refresh it. No setInterval polling is needed.</p>

<div class="manual-code" data-code-language="javascript"><div class="manual-code-toolbar"><span>JavaScript</span><span class="manual-code-tools"><small>JavaScript</small><button type="button" data-copy-code data-copied="Copied" data-failed="Select and copy the code" aria-label="Copy code: JavaScript">Copy code</button><span class="manual-code-status" role="status"></span></span></div><pre tabindex="0" class="docs-code-block shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> tag</span><span style="color:#D73A49"> =</span><span style="color:#032F62"> "&#x3C;device-code>.&#x3C;tag-code>"</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#D73A49">function</span><span style="color:#6F42C1"> renderValue</span><span style="color:#24292E">() {</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> value</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> api.</span><span style="color:#6F42C1">ReadTagDouble</span><span style="color:#24292E">(tag, </span><span style="color:#005CC5">null</span><span style="color:#24292E">);</span></span>

<span class="line"><span style="color:#24292E"> document.</span><span style="color:#6F42C1">getElementById</span><span style="color:#24292E">(</span><span style="color:#032F62">"value"</span><span style="color:#24292E">).textContent </span><span style="color:#D73A49">=</span><span style="color:#24292E"> value </span><span style="color:#D73A49">??</span><span style="color:#032F62"> "—"</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#24292E">}</span></span>

<span class="line"><span style="color:#6F42C1">renderValue</span><span style="color:#24292E">();</span></span>

<span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> stop</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> api.</span><span style="color:#6F42C1">subscribe</span><span style="color:#24292E">([tag], renderValue);</span></span>

<span class="line"><span style="color:#6A737D">// Call stop() when this view is removed.</span></span></code></pre></div>

<p class="doc-step-result"><strong>Expected result</strong> The value renders immediately and updates on change. Call stop() when the view is removed.</p>

</article>

<article class="doc-card">

<h3 id="custom-page-tutorial-item-5">Write a Tag once from a button</h3>

<p>Add &lt;button id=&quot;write&quot; disabled&gt;Write&lt;/button&gt; and &lt;pre id=&quot;result&quot;&gt;&lt;/pre&gt;. This writes 12.5 once; replace it with an allowed value. Declare the writable Tag, enable its control flag and use an account with tag:write permission.</p>

<div class="manual-code" data-code-language="javascript"><div class="manual-code-toolbar"><span>JavaScript</span><span class="manual-code-tools"><small>JavaScript</small><button type="button" data-copy-code data-copied="Copied" data-failed="Select and copy the code" aria-label="Copy code: JavaScript">Copy code</button><span class="manual-code-status" role="status"></span></span></div><pre tabindex="0" class="docs-code-block shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> button</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> document.</span><span style="color:#6F42C1">getElementById</span><span style="color:#24292E">(</span><span style="color:#032F62">"write"</span><span style="color:#24292E">);</span></span>

<span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> output</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> document.</span><span style="color:#6F42C1">getElementById</span><span style="color:#24292E">(</span><span style="color:#032F62">"result"</span><span style="color:#24292E">);</span></span>

<span class="line"><span style="color:#24292E">button.disabled </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> !</span><span style="color:#24292E">(api.</span><span style="color:#6F42C1">supports</span><span style="color:#24292E">(</span><span style="color:#032F62">"tag.write"</span><span style="color:#24292E">) </span><span style="color:#D73A49">&#x26;&#x26;</span><span style="color:#D73A49"> await</span><span style="color:#24292E"> api.auth.</span><span style="color:#6F42C1">hasPermission</span><span style="color:#24292E">(</span><span style="color:#032F62">"tag:write"</span><span style="color:#24292E">));</span></span>

<span class="line"><span style="color:#24292E">button.</span><span style="color:#6F42C1">onclick</span><span style="color:#D73A49"> =</span><span style="color:#D73A49"> async</span><span style="color:#24292E"> () </span><span style="color:#D73A49">=></span><span style="color:#24292E"> {</span></span>

<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> (button.disabled) </span><span style="color:#D73A49">return</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> tag</span><span style="color:#D73A49"> =</span><span style="color:#032F62"> "&#x3C;device-code>.&#x3C;tag-code>"</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> (</span><span style="color:#D73A49">!</span><span style="color:#24292E">api.</span><span style="color:#6F42C1">ReadTagQualityGood</span><span style="color:#24292E">(tag)) { output.textContent </span><span style="color:#D73A49">=</span><span style="color:#032F62"> "Tag unavailable"</span><span style="color:#24292E">; </span><span style="color:#D73A49">return</span><span style="color:#24292E">; }</span></span>

<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> (</span><span style="color:#D73A49">!</span><span style="color:#6F42C1">confirm</span><span style="color:#24292E">(</span><span style="color:#032F62">"Write 12.5?"</span><span style="color:#24292E">)) </span><span style="color:#D73A49">return</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#24292E"> button.disabled </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> true</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#D73A49"> try</span><span style="color:#24292E"> {</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> result</span><span style="color:#D73A49"> =</span><span style="color:#D73A49"> await</span><span style="color:#24292E"> api.</span><span style="color:#6F42C1">WriteTagDouble</span><span style="color:#24292E">(tag, </span><span style="color:#005CC5">12.5</span><span style="color:#24292E">, { reason: </span><span style="color:#032F62">"Operator setpoint update"</span><span style="color:#24292E"> });</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> done</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> result?.accepted </span><span style="color:#D73A49">===</span><span style="color:#005CC5"> true</span><span style="color:#D73A49"> &#x26;&#x26;</span><span style="color:#24292E"> result?.status </span><span style="color:#D73A49">===</span><span style="color:#032F62"> "done"</span></span>

<span class="line"><span style="color:#D73A49"> &#x26;&#x26;</span><span style="color:#24292E"> result?.outcomeUncertain </span><span style="color:#D73A49">!==</span><span style="color:#005CC5"> true</span><span style="color:#D73A49"> &#x26;&#x26;</span><span style="color:#24292E"> result?.operatorVerificationRequired </span><span style="color:#D73A49">!==</span><span style="color:#005CC5"> true</span></span>

<span class="line"><span style="color:#D73A49"> &#x26;&#x26;</span><span style="color:#24292E"> result?.transportOnly </span><span style="color:#D73A49">!==</span><span style="color:#005CC5"> true</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#24292E"> output.textContent </span><span style="color:#D73A49">=</span><span style="color:#24292E"> (done </span><span style="color:#D73A49">?</span><span style="color:#032F62"> "Command completed; verify collected value: "</span><span style="color:#D73A49"> :</span><span style="color:#032F62"> "Result unconfirmed; verify before another write: "</span><span style="color:#24292E">)</span></span>

<span class="line"><span style="color:#D73A49"> +</span><span style="color:#005CC5"> JSON</span><span style="color:#24292E">.</span><span style="color:#6F42C1">stringify</span><span style="color:#24292E">(result </span><span style="color:#D73A49">??</span><span style="color:#005CC5"> null</span><span style="color:#24292E">);</span></span>

<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">catch</span><span style="color:#24292E"> (error) {</span></span>

<span class="line"><span style="color:#24292E"> output.textContent </span><span style="color:#D73A49">=</span><span style="color:#032F62"> "Result unconfirmed: "</span><span style="color:#D73A49"> +</span><span style="color:#24292E"> error.message </span><span style="color:#D73A49">+</span><span style="color:#032F62"> " "</span><span style="color:#D73A49"> +</span><span style="color:#24292E"> (error.commandId </span><span style="color:#D73A49">||</span><span style="color:#24292E"> error.result?.commandId </span><span style="color:#D73A49">||</span><span style="color:#032F62"> ""</span><span style="color:#24292E">);</span></span>

<span class="line"><span style="color:#24292E"> }</span></span>

<span class="line"><span style="color:#6A737D"> // Reconcile the result before another write. Never retry automatically.</span></span>

<span class="line"><span style="color:#24292E">};</span></span></code></pre></div>

<p class="doc-step-result"><strong>Expected result</strong> Use WriteTagInteger or WriteTagBoolean for those types. This example submits once per page instance, then disables the button; done still requires later normal collection. Reloading resets the button. Reconcile the prior result before another action; persist pending-verification state if blocking must survive reloads.</p>

<ul class="doc-related-links">

<li><a href="/en/hqserver/manual/custom-page-sdk/#custom-page-sdk-item-14">Write-result reconciliation</a></li>

</ul>

</article>

<article class="doc-card">

<h3 id="custom-page-tutorial-item-6">Query active alarms once</h3>

<p>Add &lt;div id=&quot;alarms&quot;&gt;&lt;/div&gt; and &lt;p id=&quot;alarm-status&quot;&gt;&lt;/p&gt;. getActive queries active alarms and renderTable displays items.</p>

<div class="manual-code" data-code-language="javascript"><div class="manual-code-toolbar"><span>JavaScript</span><span class="manual-code-tools"><small>JavaScript</small><button type="button" data-copy-code data-copied="Copied" data-failed="Select and copy the code" aria-label="Copy code: JavaScript">Copy code</button><span class="manual-code-status" role="status"></span></span></div><pre tabindex="0" class="docs-code-block shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> alarms</span><span style="color:#D73A49"> =</span><span style="color:#D73A49"> await</span><span style="color:#24292E"> api.alarms.</span><span style="color:#6F42C1">getActive</span><span style="color:#24292E">({ limit: </span><span style="color:#005CC5">100</span><span style="color:#24292E"> });</span></span>

<span class="line"><span style="color:#24292E">api.</span><span style="color:#6F42C1">renderTable</span><span style="color:#24292E">(</span><span style="color:#032F62">"#alarms"</span><span style="color:#24292E">, alarms.items);</span></span>

<span class="line"><span style="color:#24292E">document.</span><span style="color:#6F42C1">getElementById</span><span style="color:#24292E">(</span><span style="color:#032F62">"alarm-status"</span><span style="color:#24292E">).textContent </span><span style="color:#D73A49">=</span><span style="color:#24292E"> alarms.hasMore </span><span style="color:#D73A49">?</span><span style="color:#032F62"> "More records available"</span><span style="color:#D73A49"> :</span><span style="color:#032F62"> ""</span><span style="color:#24292E">;</span></span></code></pre></div>

<p class="doc-step-result"><strong>Expected result</strong> This queries once. For live lists, use alarms.subscribe to trigger a new query, without appending callback data; unsubscribe on exit. Empty items means no alarms in scope; hasMore=true means more records. Configure scope for other devices or groups.</p>

<ul class="doc-related-links">

<li><a href="/en/hqserver/manual/custom-page-sdk/#custom-page-sdk-item-17">alarm scope</a></li>

</ul>

</article>

<article class="doc-card">

<h3 id="custom-page-tutorial-item-9">Read the last hour of alarm history</h3>

<p>Add &lt;div id=&quot;alarm-history&quot;&gt;&lt;/div&gt; and &lt;p id=&quot;history-status&quot;&gt;&lt;/p&gt;. Use alarms.queryHistory to display historical events in a separate table.</p>

<div class="manual-code" data-code-language="javascript"><div class="manual-code-toolbar"><span>JavaScript</span><span class="manual-code-tools"><small>JavaScript</small><button type="button" data-copy-code data-copied="Copied" data-failed="Select and copy the code" aria-label="Copy code: JavaScript">Copy code</button><span class="manual-code-status" role="status"></span></span></div><pre tabindex="0" class="docs-code-block shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> alarmEnd</span><span style="color:#D73A49"> =</span><span style="color:#D73A49"> new</span><span style="color:#6F42C1"> Date</span><span style="color:#24292E">();</span></span>

<span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> alarmHistory</span><span style="color:#D73A49"> =</span><span style="color:#D73A49"> await</span><span style="color:#24292E"> api.alarms.</span><span style="color:#6F42C1">queryHistory</span><span style="color:#24292E">({</span></span>

<span class="line"><span style="color:#24292E"> start: </span><span style="color:#D73A49">new</span><span style="color:#6F42C1"> Date</span><span style="color:#24292E">(alarmEnd.</span><span style="color:#6F42C1">getTime</span><span style="color:#24292E">() </span><span style="color:#D73A49">-</span><span style="color:#005CC5"> 3600000</span><span style="color:#24292E">).</span><span style="color:#6F42C1">toISOString</span><span style="color:#24292E">(),</span></span>

<span class="line"><span style="color:#24292E"> end: alarmEnd.</span><span style="color:#6F42C1">toISOString</span><span style="color:#24292E">(),</span></span>

<span class="line"><span style="color:#24292E"> limit: </span><span style="color:#005CC5">100</span></span>

<span class="line"><span style="color:#24292E">});</span></span>

<span class="line"><span style="color:#24292E">api.</span><span style="color:#6F42C1">renderTable</span><span style="color:#24292E">(</span><span style="color:#032F62">"#alarm-history"</span><span style="color:#24292E">, alarmHistory.items);</span></span>

<span class="line"><span style="color:#24292E">document.</span><span style="color:#6F42C1">getElementById</span><span style="color:#24292E">(</span><span style="color:#032F62">"history-status"</span><span style="color:#24292E">).textContent </span><span style="color:#D73A49">=</span><span style="color:#24292E"> alarmHistory.hasMore </span><span style="color:#D73A49">?</span><span style="color:#032F62"> "More records available"</span><span style="color:#D73A49"> :</span><span style="color:#032F62"> ""</span><span style="color:#24292E">;</span></span></code></pre></div>

</article>

<article class="doc-card">

<h3 id="custom-page-tutorial-item-7">Query trend data</h3>

<p>Enable Tag archiving and add &lt;div id=&quot;trend&quot;&gt;&lt;/div&gt; and &lt;p id=&quot;trend-status&quot;&gt;&lt;/p&gt;. This displays minute averages for the last hour as a table; pass the same points to your chart component to draw a curve.</p>

<div class="manual-code" data-code-language="javascript"><div class="manual-code-toolbar"><span>JavaScript</span><span class="manual-code-tools"><small>JavaScript</small><button type="button" data-copy-code data-copied="Copied" data-failed="Select and copy the code" aria-label="Copy code: JavaScript">Copy code</button><span class="manual-code-status" role="status"></span></span></div><pre tabindex="0" class="docs-code-block shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> trendEnd</span><span style="color:#D73A49"> =</span><span style="color:#D73A49"> new</span><span style="color:#6F42C1"> Date</span><span style="color:#24292E">();</span></span>

<span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> trend</span><span style="color:#D73A49"> =</span><span style="color:#D73A49"> await</span><span style="color:#24292E"> api.history.</span><span style="color:#6F42C1">query</span><span style="color:#24292E">({</span></span>

<span class="line"><span style="color:#24292E"> tags: [</span><span style="color:#032F62">"&#x3C;device-code>.&#x3C;tag-code>"</span><span style="color:#24292E">],</span></span>

<span class="line"><span style="color:#24292E"> start: </span><span style="color:#D73A49">new</span><span style="color:#6F42C1"> Date</span><span style="color:#24292E">(trendEnd.</span><span style="color:#6F42C1">getTime</span><span style="color:#24292E">() </span><span style="color:#D73A49">-</span><span style="color:#005CC5"> 3600000</span><span style="color:#24292E">).</span><span style="color:#6F42C1">toISOString</span><span style="color:#24292E">(),</span></span>

<span class="line"><span style="color:#24292E"> end: trendEnd.</span><span style="color:#6F42C1">toISOString</span><span style="color:#24292E">(), interval: </span><span style="color:#032F62">"1m"</span><span style="color:#24292E">, aggregate: </span><span style="color:#032F62">"avg"</span></span>

<span class="line"><span style="color:#24292E">});</span></span>

<span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> points</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> (trend.items[</span><span style="color:#005CC5">0</span><span style="color:#24292E">]?.points </span><span style="color:#D73A49">||</span><span style="color:#24292E"> []).</span><span style="color:#6F42C1">map</span><span style="color:#24292E">(</span><span style="color:#E36209">point</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> ({</span></span>

<span class="line"><span style="color:#24292E"> time: point.t, value: point.quality </span><span style="color:#D73A49">===</span><span style="color:#032F62"> "good"</span><span style="color:#D73A49"> ?</span><span style="color:#24292E"> point.value </span><span style="color:#D73A49">:</span><span style="color:#005CC5"> null</span></span>

<span class="line"><span style="color:#24292E">}));</span></span>

<span class="line"><span style="color:#24292E">api.</span><span style="color:#6F42C1">renderTable</span><span style="color:#24292E">(</span><span style="color:#032F62">"#trend"</span><span style="color:#24292E">, points);</span></span>

<span class="line"><span style="color:#24292E">document.</span><span style="color:#6F42C1">getElementById</span><span style="color:#24292E">(</span><span style="color:#032F62">"trend-status"</span><span style="color:#24292E">).textContent </span><span style="color:#D73A49">=</span><span style="color:#24292E"> trend.effectiveInterval;</span></span></code></pre></div>

<p class="doc-step-result"><strong>Expected result</strong> No archive produces empty data. Keep gaps for bad-quality points using null. effectiveInterval reports the actual interval.</p>

</article>

<article class="doc-card">

<h3 id="sdk-scenario-popup">Open an equipment popup</h3>

<p>Save a template in Popup Templates, add &lt;button id=&quot;open-popup&quot;&gt;Open equipment&lt;/button&gt;, then bind its click. Replace the device, template and declared Tag codes.</p>

<div class="manual-code" data-code-language="javascript"><div class="manual-code-toolbar"><span>JavaScript</span><span class="manual-code-tools"><small>JavaScript</small><button type="button" data-copy-code data-copied="Copied" data-failed="Select and copy the code" aria-label="Copy code: JavaScript">Copy code</button><span class="manual-code-status" role="status"></span></span></div><pre tabindex="0" class="docs-code-block shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">document.</span><span style="color:#6F42C1">getElementById</span><span style="color:#24292E">(</span><span style="color:#032F62">"open-popup"</span><span style="color:#24292E">).</span><span style="color:#6F42C1">onclick</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> () </span><span style="color:#D73A49">=></span><span style="color:#24292E"> {</span></span>

<span class="line"><span style="color:#D73A49"> try</span><span style="color:#24292E"> {</span></span>

<span class="line"><span style="color:#24292E"> api.dialog.</span><span style="color:#6F42C1">openDevicePopup</span><span style="color:#24292E">({</span></span>

<span class="line"><span style="color:#24292E"> plc: </span><span style="color:#032F62">"&#x3C;device-code>"</span><span style="color:#24292E">,</span></span>

<span class="line"><span style="color:#24292E"> templateCode: </span><span style="color:#032F62">"&#x3C;popup-template-code>"</span><span style="color:#24292E">,</span></span>

<span class="line"><span style="color:#24292E"> focusTagNames: [</span><span style="color:#032F62">"&#x3C;device-code>.&#x3C;tag-code>"</span><span style="color:#24292E">]</span></span>

<span class="line"><span style="color:#24292E"> });</span></span>

<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">catch</span><span style="color:#24292E"> (error) { console.</span><span style="color:#6F42C1">error</span><span style="color:#24292E">(error.message); }</span></span>

<span class="line"><span style="color:#24292E">};</span></span></code></pre></div>

<p class="doc-step-result"><strong>Expected result</strong> The template defines displayed values, controls, alarms and trends. Dispatching the popup is not a write receipt; verify the visible popup and target values.</p>

</article>

<article class="doc-card">

<h3 id="sdk-scenario-navigation">Navigate to another page</h3>

<p>Choose one call for your button click handler. Relative paths start from the current screen; parent, child and other folders are allowed within the assets root.</p>

<div class="manual-code" data-code-language="javascript"><div class="manual-code-toolbar"><span>JavaScript</span><span class="manual-code-tools"><small>JavaScript</small><button type="button" data-copy-code data-copied="Copied" data-failed="Select and copy the code" aria-label="Copy code: JavaScript">Copy code</button><span class="manual-code-status" role="status"></span></span></div><pre tabindex="0" class="docs-code-block shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">// Use one of these calls in your button's click handler:</span></span>

<span class="line"><span style="color:#24292E">api.navigation.</span><span style="color:#6F42C1">gotoPage</span><span style="color:#24292E">(</span><span style="color:#032F62">"details/equipment.html"</span><span style="color:#24292E">); </span><span style="color:#6A737D">// Child page</span></span>

<span class="line"><span style="color:#24292E">api.navigation.</span><span style="color:#6F42C1">gotoPage</span><span style="color:#24292E">(</span><span style="color:#032F62">"../overview.html"</span><span style="color:#24292E">); </span><span style="color:#6A737D">// Parent page</span></span>

<span class="line"><span style="color:#24292E">api.navigation.</span><span style="color:#6F42C1">gotoPage</span><span style="color:#24292E">(</span><span style="color:#032F62">"/assets/&#x3C;folder>/index.html"</span><span style="color:#24292E">); </span><span style="color:#6A737D">// Another folder</span></span>

<span class="line"><span style="color:#24292E">api.navigation.</span><span style="color:#6F42C1">openUrl</span><span style="color:#24292E">(</span><span style="color:#032F62">"https://&#x3C;server-host>/manual"</span><span style="color:#24292E">, { openInNewWindow: </span><span style="color:#005CC5">true</span><span style="color:#24292E"> });</span></span></code></pre></div>

</article>

<article class="doc-card">

<h3 id="sdk-scenario-language">Follow the system language</h3>

<p>The top-bar LANG control already switches languages. Give your title id=&quot;title&quot;, read the current language and subscribe to changes.</p>

<div class="manual-code" data-code-language="javascript"><div class="manual-code-toolbar"><span>JavaScript</span><span class="manual-code-tools"><small>JavaScript</small><button type="button" data-copy-code data-copied="Copied" data-failed="Select and copy the code" aria-label="Copy code: JavaScript">Copy code</button><span class="manual-code-status" role="status"></span></span></div><pre tabindex="0" class="docs-code-block shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">function</span><span style="color:#6F42C1"> renderText</span><span style="color:#24292E">() {</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> zh</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> api.language.</span><span style="color:#6F42C1">current</span><span style="color:#24292E">().</span><span style="color:#6F42C1">startsWith</span><span style="color:#24292E">(</span><span style="color:#032F62">"zh"</span><span style="color:#24292E">);</span></span>

<span class="line"><span style="color:#24292E"> document.</span><span style="color:#6F42C1">getElementById</span><span style="color:#24292E">(</span><span style="color:#032F62">"title"</span><span style="color:#24292E">).textContent </span><span style="color:#D73A49">=</span><span style="color:#24292E"> zh </span><span style="color:#D73A49">?</span><span style="color:#032F62"> "设备总览"</span><span style="color:#D73A49"> :</span><span style="color:#032F62"> "Equipment overview"</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#24292E">}</span></span>

<span class="line"><span style="color:#6F42C1">renderText</span><span style="color:#24292E">();</span></span>

<span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> stopLanguage</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> api.language.</span><span style="color:#6F42C1">onChange</span><span style="color:#24292E">(renderText);</span></span>

<span class="line"><span style="color:#6A737D">// Call stopLanguage() when this view is removed.</span></span></code></pre></div>

</article>

<article class="doc-card">

<h3 id="tutorial-sdk-vue-component">Use the same API in Vue</h3>

<p>In Vue 3, add layout and Tag declarations to index.html, then save and mount this complete read-only component. Obtain api in onMounted. Runtime loads the SDK after publishing.</p>

<div class="manual-code" data-code-language="vue"><div class="manual-code-toolbar"><span>Vue</span><span class="manual-code-tools"><small>Vue</small><button type="button" data-copy-code data-copied="Copied" data-failed="Select and copy the code" aria-label="Copy code: Vue">Copy code</button><span class="manual-code-status" role="status"></span></span></div><pre tabindex="0" class="docs-code-block shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">script</span><span style="color:#6F42C1"> setup</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#D73A49">import</span><span style="color:#24292E"> { ref, onMounted, onUnmounted } </span><span style="color:#D73A49">from</span><span style="color:#032F62"> "vue"</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> value</span><span style="color:#D73A49"> =</span><span style="color:#6F42C1"> ref</span><span style="color:#24292E">(</span><span style="color:#005CC5">null</span><span style="color:#24292E">), </span><span style="color:#005CC5">error</span><span style="color:#D73A49"> =</span><span style="color:#6F42C1"> ref</span><span style="color:#24292E">(</span><span style="color:#032F62">""</span><span style="color:#24292E">);</span></span>

<span class="line"><span style="color:#D73A49">let</span><span style="color:#24292E"> stop, disposed </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> false</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#6F42C1">onMounted</span><span style="color:#24292E">(</span><span style="color:#D73A49">async</span><span style="color:#24292E"> () </span><span style="color:#D73A49">=></span><span style="color:#24292E"> {</span></span>

<span class="line"><span style="color:#D73A49"> try</span><span style="color:#24292E"> {</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> api</span><span style="color:#D73A49"> =</span><span style="color:#D73A49"> await</span><span style="color:#24292E"> window.</span><span style="color:#005CC5">HQVISU_CUSTOM_PAGE</span><span style="color:#24292E">.</span><span style="color:#6F42C1">ready</span><span style="color:#24292E">();</span></span>

<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> (disposed) </span><span style="color:#D73A49">return</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> tag</span><span style="color:#D73A49"> =</span><span style="color:#032F62"> "&#x3C;device-code>.&#x3C;tag-code>"</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#6F42C1"> refresh</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> () </span><span style="color:#D73A49">=></span><span style="color:#24292E"> { value.value </span><span style="color:#D73A49">=</span><span style="color:#24292E"> api.</span><span style="color:#6F42C1">ReadTagDouble</span><span style="color:#24292E">(tag, </span><span style="color:#005CC5">null</span><span style="color:#24292E">); };</span></span>

<span class="line"><span style="color:#6F42C1"> refresh</span><span style="color:#24292E">();</span></span>

<span class="line"><span style="color:#24292E"> stop </span><span style="color:#D73A49">=</span><span style="color:#24292E"> api.</span><span style="color:#6F42C1">subscribe</span><span style="color:#24292E">([tag], refresh);</span></span>

<span class="line"><span style="color:#24292E"> } </span><span style="color:#D73A49">catch</span><span style="color:#24292E"> (err) { </span><span style="color:#D73A49">if</span><span style="color:#24292E"> (</span><span style="color:#D73A49">!</span><span style="color:#24292E">disposed) error.value </span><span style="color:#D73A49">=</span><span style="color:#24292E"> err.message; }</span></span>

<span class="line"><span style="color:#24292E">});</span></span>

<span class="line"><span style="color:#6F42C1">onUnmounted</span><span style="color:#24292E">(() </span><span style="color:#D73A49">=></span><span style="color:#24292E"> { disposed </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> true</span><span style="color:#24292E">; </span><span style="color:#6F42C1">stop</span><span style="color:#24292E">?.(); });</span></span>

<span class="line"><span style="color:#24292E">&#x3C;/</span><span style="color:#22863A">script</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">template</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E"> &#x3C;</span><span style="color:#22863A">p</span><span style="color:#6F42C1"> v-if</span><span style="color:#24292E">=</span><span style="color:#032F62">"error"</span><span style="color:#24292E">>{{ error }}&#x3C;/</span><span style="color:#22863A">p</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E"> &#x3C;</span><span style="color:#22863A">output</span><span style="color:#6F42C1"> v-else</span><span style="color:#24292E">>{{ value ?? "—" }}&#x3C;/</span><span style="color:#22863A">output</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;/</span><span style="color:#22863A">template</span><span style="color:#24292E">></span></span></code></pre></div>

<p class="doc-step-result"><strong>Expected result</strong> Set Vite base: &quot;./&quot; and upload dist contents with their folder structure. On unmount, cancel only component subscriptions; do not call api.destroy(). Here api is local to onMounted; retain it in component scope for buttons, as in the full Vue write example.</p>

<ul class="doc-related-links">

<li><a href="/en/hqserver/manual/custom-page-sdk/#sdk-vue-component">complete Vue write example</a></li>

</ul>

</article>

<article class="doc-card">

<h3 id="custom-page-tutorial-item-2">Complete HTML: replace Tags, then publish</h3>

<p>Start from this complete read-only page and replace both occurrences of the Tag code. It uses the SDK supplied by Runtime.</p>

<details class="manual-code-disclosure"><summary>View complete source</summary><div class="manual-code" data-code-language="html"><div class="manual-code-toolbar"><span>HTML</span><span class="manual-code-tools"><small>HTML</small><button type="button" data-copy-code data-copied="Copied" data-failed="Select and copy the code" aria-label="Copy code: HTML">Copy code</button><span class="manual-code-status" role="status"></span></span></div><pre tabindex="0" class="docs-code-block shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">&#x3C;!</span><span style="color:#22863A">doctype</span><span style="color:#6F42C1"> html</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">html</span><span style="color:#6F42C1"> lang</span><span style="color:#24292E">=</span><span style="color:#032F62">"en"</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">meta</span><span style="color:#6F42C1"> charset</span><span style="color:#24292E">=</span><span style="color:#032F62">"utf-8"</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">meta</span><span style="color:#6F42C1"> name</span><span style="color:#24292E">=</span><span style="color:#032F62">"viewport"</span><span style="color:#6F42C1"> content</span><span style="color:#24292E">=</span><span style="color:#032F62">"width=device-width, initial-scale=1"</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">title</span><span style="color:#24292E">>Mingcedar live value&#x3C;/</span><span style="color:#22863A">title</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">script</span><span style="color:#6F42C1"> type</span><span style="color:#24292E">=</span><span style="color:#032F62">"application/json"</span><span style="color:#6F42C1"> id</span><span style="color:#24292E">=</span><span style="color:#032F62">"hqvisu-custom-page"</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">{"readableTags":["&#x3C;device-code>.&#x3C;process-tag-code>"],"writableTags":[]}</span></span>

<span class="line"><span style="color:#24292E">&#x3C;/</span><span style="color:#22863A">script</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">script</span><span style="color:#24292E">>window.</span><span style="color:#005CC5">HQVISU_PAGE_META</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> { layoutMode: </span><span style="color:#032F62">"native"</span><span style="color:#24292E"> };&#x3C;/</span><span style="color:#22863A">script</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">h1</span><span style="color:#24292E">>Live value&#x3C;/</span><span style="color:#22863A">h1</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">p</span><span style="color:#6F42C1"> id</span><span style="color:#24292E">=</span><span style="color:#032F62">"status"</span><span style="color:#6F42C1"> role</span><span style="color:#24292E">=</span><span style="color:#032F62">"status"</span><span style="color:#24292E">>Connecting…&#x3C;/</span><span style="color:#22863A">p</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">output</span><span style="color:#6F42C1"> id</span><span style="color:#24292E">=</span><span style="color:#032F62">"value"</span><span style="color:#24292E">>Waiting for data&#x3C;/</span><span style="color:#22863A">output</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">script</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">(</span><span style="color:#D73A49">async</span><span style="color:#24292E"> () </span><span style="color:#D73A49">=></span><span style="color:#24292E"> {</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> tag</span><span style="color:#D73A49"> =</span><span style="color:#032F62"> "&#x3C;device-code>.&#x3C;process-tag-code>"</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> status</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> document.</span><span style="color:#6F42C1">getElementById</span><span style="color:#24292E">(</span><span style="color:#032F62">"status"</span><span style="color:#24292E">);</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> output</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> document.</span><span style="color:#6F42C1">getElementById</span><span style="color:#24292E">(</span><span style="color:#032F62">"value"</span><span style="color:#24292E">);</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> api</span><span style="color:#D73A49"> =</span><span style="color:#D73A49"> await</span><span style="color:#005CC5"> HQVISU_CUSTOM_PAGE</span><span style="color:#24292E">.</span><span style="color:#6F42C1">ready</span><span style="color:#24292E">({timeoutMs: </span><span style="color:#005CC5">10000</span><span style="color:#24292E">});</span></span>

<span class="line"><span style="color:#D73A49"> function</span><span style="color:#6F42C1"> refresh</span><span style="color:#24292E">() {</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> quality</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> api.</span><span style="color:#6F42C1">ReadTagQuality</span><span style="color:#24292E">(tag);</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> value</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> api.</span><span style="color:#6F42C1">ReadTagDouble</span><span style="color:#24292E">(tag, </span><span style="color:#005CC5">null</span><span style="color:#24292E">);</span></span>

<span class="line"><span style="color:#24292E"> status.textContent </span><span style="color:#D73A49">=</span><span style="color:#032F62"> "Connected — quality: "</span><span style="color:#D73A49"> +</span><span style="color:#24292E"> quality;</span></span>

<span class="line"><span style="color:#24292E"> output.textContent </span><span style="color:#D73A49">=</span><span style="color:#24292E"> quality </span><span style="color:#D73A49">===</span><span style="color:#032F62"> "good"</span><span style="color:#D73A49"> &#x26;&#x26;</span><span style="color:#24292E"> value </span><span style="color:#D73A49">!==</span><span style="color:#005CC5"> null</span></span>

<span class="line"><span style="color:#D73A49"> ?</span><span style="color:#6F42C1"> String</span><span style="color:#24292E">(value) </span><span style="color:#D73A49">:</span><span style="color:#032F62"> "Unavailable"</span><span style="color:#24292E">;</span></span>

<span class="line"><span style="color:#24292E"> }</span></span>

<span class="line"><span style="color:#D73A49"> const</span><span style="color:#005CC5"> stop</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> api.</span><span style="color:#6F42C1">subscribe</span><span style="color:#24292E">([tag], refresh);</span></span>

<span class="line"><span style="color:#6F42C1"> refresh</span><span style="color:#24292E">();</span></span>

<span class="line"><span style="color:#24292E"> window.</span><span style="color:#6F42C1">addEventListener</span><span style="color:#24292E">(</span><span style="color:#032F62">"pagehide"</span><span style="color:#24292E">, </span><span style="color:#E36209">event</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> {</span></span>

<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> (</span><span style="color:#D73A49">!</span><span style="color:#24292E">event.persisted) { </span><span style="color:#6F42C1">stop</span><span style="color:#24292E">(); api.</span><span style="color:#6F42C1">destroy</span><span style="color:#24292E">(); }</span></span>

<span class="line"><span style="color:#24292E"> });</span></span>

<span class="line"><span style="color:#24292E">})().</span><span style="color:#6F42C1">catch</span><span style="color:#24292E">(</span><span style="color:#E36209">error</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> {</span></span>

<span class="line"><span style="color:#24292E"> document.</span><span style="color:#6F42C1">getElementById</span><span style="color:#24292E">(</span><span style="color:#032F62">"status"</span><span style="color:#24292E">).textContent </span><span style="color:#D73A49">=</span><span style="color:#24292E"> error.message;</span></span>

<span class="line"><span style="color:#24292E">});</span></span>

<span class="line"><span style="color:#24292E">&#x3C;/</span><span style="color:#22863A">script</span><span style="color:#24292E">></span></span>

<span class="line"><span style="color:#24292E">&#x3C;/</span><span style="color:#22863A">html</span><span style="color:#24292E">></span></span></code></pre></div></details>

</article>

<article class="doc-card">

<h3 id="custom-page-tutorial-item-3">Publish it to the runtime</h3>

<ol>

<li>Configuration → Screen Files: upload HTML, or the Vue dist contents with folders intact.</li>

<li>Configuration → Menus: choose Page (open HTML directly) and select the uploaded HTML.</li>

<li>Open it from the runtime menu. Verify the Tag value, then the required actions. Republish and refresh after edits.</li>

</ol>

</article>

<article class="doc-card">

<h3 id="custom-page-tutorial-item-11">Troubleshooting</h3>

<ul>

<li>HQVISU_CUSTOM_PAGE is undefined: open the page from the current Runtime menu; standalone websites do not provide the SDK.</li>

<li>A read returns null: check the declaration, full Tag code and quality.</li>

<li>Writes are unavailable: check writableTags, account permission and the Tag control flag. Reconcile unknown outcomes before another operation.</li>

<li>For more types and options, use the API reference.</li>

</ul>

<ul class="doc-related-links">

<li><a href="/en/hqserver/manual/custom-page-sdk/">API reference</a></li>

</ul>

</article>

<article class="doc-card">

<h3 id="sdk-development-brief">Page delivery information</h3>

<p>For development and acceptance, provide actual Tag codes and types, allowed write values, required page behavior, and the target runtime menu. The entry HTML declarations must match the page code.</p>

<ul>

<li>List the Tag, alarm, and history scopes. For each write target, specify account permission, control access, and the equipment&#39;s allowed values.</li>

<li>Open the page from the runtime menu and check SDK initialization, GOOD quality, system LANG changes, and subscription cleanup on component unmount.</li>

<li>Check write receipts against subsequent normal collected values. Preserve command identity for uncertain outcomes and reconcile before the next operation.</li>

<li>Complete missing codes, types, or authorization scopes before publishing.</li>

</ul>

<ul class="doc-related-links">

<li><a href="/en/hqserver/manual/custom-page-sdk/">API reference</a></li>

</ul>

</article>

</div>

</div>