Problem Overview
Custom Dynamic SVG widgets authored in the TIA Portal Graphics editor render correctly in the development environment but fail to display in the WinCC Unified client browser during PLCSim or runtime simulation. The editor silently accepts parameter declarations that use upper-case or vendor-specific type identifiers such as type="BOOL", while the runtime widget engine in the client discards the entire SVG, leaving a blank area in the HMI screen. The TIA Portal compiler never raises an error or warning, which makes the defect invisible until the project is started in the simulator or transferred to a real Unified Panel. The fix is to use the canonical lower-case type identifier boolean with an explicit default attribute on every <hmi:paramDef> element.
Environment and Affected Versions
| Component | Affected Versions | Notes |
|---|---|---|
| TIA Portal | V16, V17, V18, V18 SP1, V19 | Defect confirmed across all currently supported WinCC Unified releases |
| WinCC Unified Runtime | V16, V17, V18, V19 | Client browser runtime is Chromium-based (Electron shell, Edge WebView2 backend in V19) |
| WinCC Comfort/Advanced | Not affected | Custom Dynamic SVG is a Unified-only feature; Comfort/Advanced do not expose hmi:paramDef
|
| Custom Web Control | All Unified versions | Editor is permissive, runtime is strict by design |
| HMI device target | Comfort Panel, Unified Panel, PC Runtime | Issue lives in the widget schema, not in the device firmware |
The defect is independent of the WinCC Unified device target and independent of the HMI device firmware version. It is reproducible in PLCSim, in the PC Runtime simulator, and on a physical Unified Comfort Panel of any generation. The relevant TIA Portal and WinCC Unified documentation is available from Siemens Industry Online Support; the canonical manuals for TIA Portal V18 and V19 with the WinCC Unified system manual are entry IDs 109769928 and 109969600.
Symptoms
The following symptoms are characteristic of this defect and should be checked before assuming a network, runtime, or licensing issue:
- The Custom Dynamic SVG appears in the TIA Portal Graphics editor and updates correctly when the engineer manipulates input tags or properties in the Properties pane.
- The TIA Portal project compiles without errors and without warnings, and the build is reported as successful in the information area at the bottom of the IDE.
- When the project is started in the simulator (Start → Simulation → Start with runtime) or loaded onto a real Panel, the screen area that should host the widget is blank in the runtime window.
- The browser developer tools (F12) opened inside the WinCC Unified client do not show any console error related to the SVG. The widget is simply not present in the DOM tree, or the SVG element is present but has zero visible children.
- When the same widget is re-imported as a static SVG (not a custom dynamic widget) it displays correctly, confirming that the SVG graphics content itself is valid.
- The same
.SVGhmifile transferred to a second engineering station behaves identically, ruling out a local environment issue.
Root Cause
Custom Dynamic SVG widgets in WinCC Unified follow the SVG 1.1 specification extended with the Siemens HMI namespace http://www.siemens.com/automation/HMI/SVG using the hmi: prefix. The widget parameter declarations are placed in the <defs> section of the SVG file by one or more <hmi:paramDef> elements. Each <hmi:paramDef> element carries a name, a type, and an optional default attribute.
The type attribute is a fixed enumeration interpreted in lower case. According to the Custom Web Control XSD published with WinCC Unified, only the following identifiers are valid:
| Type Identifier (exact) | Meaning | Default Attribute |
|---|---|---|
boolean |
True / false value | Recommended: default="false" or default="true"
|
int or integer
|
32-bit signed integer | Recommended: numeric literal such as default="0"
|
float or number
|
64-bit floating point | Recommended: numeric literal such as default="0.0"
|
string |
UTF-8 string | Optional but recommended |
color |
Hex color string (#RRGGBB) |
Optional but recommended |
datetime |
ISO 8601 date/time | Optional |
The TIA Portal Graphics editor performs a case-insensitive lookup and accepts BOOL, Boolean, bool, and BOOLEAN as if they were valid. The runtime widget loader in the WinCC Unified client uses a case-sensitive comparison and silently discards the parameter definition, which in turn causes the entire widget instance to be rejected by the client browser. The compiler never produces a warning because the editor treats the type identifier as an opaque string and does not validate it against the published XSD.
type attribute and tolerates camel case, all-caps, and unknown identifiers. The WinCC Unified runtime, by contrast, ships a bundled Chromium build with a strict JavaScript bridge that loads the widget XML, validates every <hmi:paramDef> against the Custom Web Control XSD, and only mounts the widget if validation passes. Any unknown attribute, missing namespace, or bad type identifier causes the entire <defs> block to be rejected and the widget to be silently dropped from the DOM.Reproduction
Create a minimal custom Dynamic SVG widget with the following content saved as BlinkTact.SVGhmi in the project library:
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:hmi="http://www.siemens.com/automation/HMI/SVG"
viewBox="0 0 100 100">
<defs>
<hmi:paramDef name="BlinkTact" type="BOOL" />
<hmi:paramDef name="BlinkColor" type="STRING" default="Lime" />
</defs>
<rect x="10" y="10" width="80" height="80"
fill="<hmi:bind type="attribute" name="fill" param="BlinkColor" />"
opacity="<hmi:bind type="attribute" name="opacity" param="BlinkTact" />" />
</svg>
Add the widget to an HMI screen through Toolbox → Dynamic widgets, wire a Boolean tag to BlinkTact and a string tag to BlinkColor, and start the simulation. The TIA Portal Graphics editor shows a green rectangle; the WinCC Unified client shows nothing in the widget area. The browser dev tools (F12) confirm that the <svg> element is either absent from the DOM or contains only the broken <defs> block.
Step-by-Step Resolution
- Close the TIA Portal project. Editing a
.SVGhmifile while the project is open can cause a checksum mismatch the next time the project is opened. - Open the offending
.SVGhmifile in any UTF-8 capable text editor. Notepad++, Visual Studio Code, or the built-in Project library → Edit master copy editor are all suitable. - Locate every
<hmi:paramDef>element. TIA Portal stores custom widgets as XML inside the project archive; the file can also be extracted with Project → Library → Export master copy or by browsing to the project working folder in TIA Portal V18 and later with the new project layout. - Replace
type="BOOL"withtype="boolean"and adddefault="false". - Replace
type="STRING"withtype="string". - Replace
type="INT"withtype="int"(orinteger),type="REAL"withtype="float", andtype="DINT"withtype="int". - Save the file as UTF-8 (no BOM) and re-import it into the project library using Project library → Update.
- Drop a fresh instance of the widget onto the HMI screen; do not reuse the broken instance, as the runtime may keep a cached compiled copy of the old widget.
- Recompile the project (Project → Compile → Software (rebuild all)) and start the simulator.
The corrected widget file is:
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:hmi="http://www.siemens.com/automation/HMI/SVG"
viewBox="0 0 100 100">
<defs>
<hmi:paramDef name="BlinkTact" type="boolean" default="false" />
<hmi:paramDef name="BlinkColor" type="string" default="Lime" />
</defs>
<rect x="10" y="10" width="80" height="80"
fill="<hmi:bind type="attribute" name="fill" param="BlinkColor" />"
opacity="<hmi:bind type="attribute" name="opacity" param="BlinkTact" />" />
</svg>
Verification
- Right-click the widget instance in the HMI screen and select Properties → Compile / check consistency. No warnings or errors should be reported.
- Start the simulation (Online → Simulation → Start). The widget should appear in the WinCC Unified client window with the default values applied.
- Open the runtime browser dev tools with
F12and inspect the widget element. The<svg>root should contain the<defs>with the resolved<hmi:paramDef>blocks and the<rect>child with the bound attributes. - Toggle the PLC tag wired to
BlinkTactand confirm that theopacityattribute of the rectangle animates between 1.0 and 0.0 in the live DOM. The animation should be visible in the Computed tab of the dev tools as well. - Change the value of the string tag wired to
BlinkColorto a valid CSS color name (e.g.Red,#FF0000,rgb(255,0,0)) and confirm that the rectangle fill changes accordingly.
Browser-Side Diagnostics
When a custom Dynamic SVG fails to render in the client, always open the Chromium developer tools inside the runtime shell. The Unified client uses the embedded Chromium debugger that can be reached by pressing F12 in the runtime window, or by enabling Runtime settings → Services → Enable web server and connecting to the published port (default 8000 for PC Runtime). Look for the following markers:
| Console Output | Meaning | Likely Cause |
|---|---|---|
| (no message, blank area) | Widget discarded at parse time | Invalid type identifier, missing default attribute, or missing namespace declaration |
Uncaught TypeError: Cannot read properties of null (reading 'paramDef') |
Widget XML could not be parsed | XML well-formedness issue, special character, or wrong encoding |
Refused to apply style from 'data:text/css,...' |
Inline CSS rejected by Content Security Policy | External font or stylesheet embedded in SVG |
net::ERR_FILE_NOT_FOUND for SVGhmi resource |
Widget not embedded into project | SVG linked with Save and link instead of embedded with Save only |
Refused to execute inline script |
Inline JavaScript blocked | Embedded <script> tag in SVG; runtime CSP forbids inline scripts |
hmi:bind not resolved, attribute stays literal |
Binding not recognised |
param name does not match any hmi:paramDef
|
Related Defects and Variations
Several closely related parameter declaration errors cause the same blank-widget symptom. The following table summarises the variants and the recommended fix:
| Defective Declaration | Symptom | Correct Fix |
|---|---|---|
type="BOOL" (upper case) |
Editor OK, client blank | type="boolean" default="false" |
type="Int32" |
Editor OK, client blank | type="int" default="0" |
type="Real" |
Editor OK, client blank | type="float" default="0.0" |
type="DInt" or type="LReal"
|
Editor OK, client blank |
type="int" or type="float" as appropriate |
type="String" |
Editor OK, client blank | type="string" |
Missing default on numeric |
Editor OK, client may show 0 or fail | Add explicit numeric default |
Missing xmlns:hmi namespace |
Compile error: unknown prefix | Add xmlns:hmi="http://www.siemens.com/automation/HMI/SVG"
|
No <defs> block |
Widget shows but no parameter binding | Wrap all hmi:paramDef in <defs>
|
| Linked instead of embedded SVG | Client path resolution fails | Use Project library → Save not Save and link |
UTF-8 BOM in .SVGhmi
|
Editor OK, client blank | Save as UTF-8 without BOM |
type="int" with default="false"
|
Editor OK, client may show 0 | Use numeric default such as default="0"
|
Editor vs Runtime Pipeline
The discrepancy between the editor and the runtime is the root of the confusion. The two pipelines are not the same code base and do not share the same parser:
- The TIA Portal Graphics editor renders the widget through the IDE's internal WebView2 control. It performs a fuzzy match on the
typeattribute and tolerates camel case, all-caps, and unknown identifiers. The editor's purpose is to let the engineer lay out the screen and inspect parameter bindings in the Properties pane; it does not enforce strict schema compliance. - The WinCC Unified runtime ships a bundled Chromium build with a custom JavaScript bridge that loads the widget XML, validates the
<hmi:paramDef>entries against the published Custom Web Control XSD, and only mounts the widget if validation passes. Any unknown attribute, missing namespace, or bad type identifier causes the widget to be silently dropped.
This is by design. The strict validation in the runtime protects the operator HMI from undefined behaviour, but it also means that the TIA Portal compiler cannot be trusted to catch every error. Engineers must validate custom Dynamic SVG widgets in the actual runtime before considering the screen ready for production. The TIA Portal V18 WinCC Unified manual describes the Custom Web Control XSD in the programming reference section.
Best Practices for Custom Dynamic SVG Widgets
-
Use the canonical lower-case type names. Stick to
boolean,int,float,string,color, anddatetime. Never use Pascal case, upper case, or PLC-typed names such asBOOL,INT,REAL, orSTRING. -
Always provide a
defaultattribute on every<hmi:paramDef>. The runtime uses the default when the tag is not wired to a PLC address; the absence of a default can trigger a separate runtime error or fall back to undefined behaviour. - Validate in the runtime, not in the editor. Run the simulation on a real Unified Panel or PC Runtime before signing off. The editor's permissive parser hides defects that the runtime will reject.
- Embed the SVG, do not link it. Use Project library → Save instead of Save and link. Linked SVGs rely on a file path that may not exist on the target runtime.
-
Declare the HMI namespace explicitly. The namespace
http://www.siemens.com/automation/HMI/SVGmust be present on the root<svg>element, otherwise the runtime parser fails to recognise thehmi:prefix. -
Keep the SVG file UTF-8 encoded without BOM. Some versions of the WinCC Unified runtime reject files saved with a UTF-8 BOM or with Windows-1252 encoding; the first three bytes
EF BB BFare interpreted as malformed XML and the widget is discarded. - Version-pin the widget in the project library. When the widget is updated, increment the version in Project library → Master copies to force a recompile of every consumer. The runtime uses a content hash of the widget XML to decide whether to recompile; a version bump guarantees the recompile.
-
Avoid CSS and JavaScript that depend on external resources. The runtime Content Security Policy blocks external stylesheets, fonts, and scripts. Inline any CSS directly in the SVG with a
<style>element and avoid<script>tags entirely. - Keep the widget under 200 KB. Large widgets with embedded base64 raster data slow down the editor preview and the runtime load. Use SVG vector primitives and Unicode glyphs wherever possible.
- Test with the actual PLC tag types. Wire every parameter to a real PLC address and confirm that the binding works in both directions, not just in the editor preview.
Caching and Reload Considerations
After replacing the SVG file, the WinCC Unified runtime keeps a cached copy of the compiled widget in the project archive on the target device. The cached copy is invalidated only when the project is recompiled and reloaded. To force a clean state during development:
- Stop the runtime simulator.
- Delete the
~tmpfolder under the working directory of the project (e.g.C:\ProgramData\Siemens\Automation\ProjectFiles\<ProjectName>\~tmpon PC Runtime). - Recompile the project in TIA Portal.
- Restart the simulator.
For real Panel targets, perform a full project transfer (Online → Extended download to device → Replace project) rather than a delta download. The full transfer clears the widget cache on the Panel and forces a fresh compile of every custom widget. After the transfer, restart the Panel runtime from the Control Panel → Runtime → Restart dialog to ensure the new widget is loaded.
Field-Proven Diagnostic Checklist
When a custom Dynamic SVG does not render in the WinCC Unified client, run through the following checklist in order. The first match typically identifies the root cause:
- Open the
.SVGhmifile in a text editor and confirm that everyhmi:paramDefuses a canonical lower-casetypeidentifier. - Confirm that every
hmi:paramDefhas adefaultattribute. - Confirm that the file is encoded as UTF-8 without BOM (open in a hex editor and check the first three bytes are
3C 3F 78for<?x). - Confirm that the root
<svg>element declares thexmlns:hmi="http://www.siemens.com/automation/HMI/SVG"namespace. - Confirm that the
hmi:paramDefelements are wrapped in a<defs>block. - Confirm that the widget is embedded in the project (Project library → Master copies) and not just linked to a file on disk.
- Open the runtime browser dev tools with
F12and check the console for the markers listed in the Browser-Side Diagnostics table above. - Inspect the live DOM and confirm that the
<svg>element is present and contains the expected children. - Toggle the wired PLC tag and confirm that the bound attribute updates in the DOM.
- If the widget still does not render, export the project library to a clean folder, recreate the widget from scratch, and re-import.
Why the Compiler Cannot Catch This Defect
The TIA Portal compiler in V16 through V19 performs a syntactic check on the HMI project but does not validate the contents of custom Dynamic SVG widgets against the Custom Web Control XSD. The compiler treats the <hmi:paramDef> elements as opaque XML and never inspects the type attribute. This is a documented limitation of the build pipeline: the schema validation is delegated to the runtime, which performs a strict case-sensitive check on the type identifier.
The consequence is that a widget can pass the compile step and still fail in the runtime. The only reliable validation is to start the simulator and inspect the widget in the browser dev tools. For projects with many custom widgets, consider adding a CI step that runs a simple XML parser against the .SVGhmi files to check for canonical type names and default attributes before the project is committed to the version control system.
FAQ
Why does the TIA Portal Graphics editor show my custom Dynamic SVG correctly but the WinCC Unified client shows a blank area?
The editor uses a permissive SVG parser that accepts parameter declarations such as type="BOOL", while the WinCC Unified runtime uses a strict schema parser that only recognises the lower-case canonical type identifiers boolean, int, float, string, color, and datetime. When the runtime encounters an unknown type it silently drops the entire widget from the DOM.
Does the TIA Portal compiler report the wrong type identifier as an error or warning?
No. The TIA Portal compiler in V16 through V19 treats the type attribute as an opaque string and never reports a problem. The only way to catch the issue is to start the simulator, open the runtime browser dev tools with F12, and inspect the widget DOM or the console output.
Which type identifiers are valid in <hmi:paramDef> for WinCC Unified custom Dynamic SVG widgets?
The valid type identifiers are boolean, int (or integer), float (or number), string, color, and datetime. Pascal case, upper case, and vendor-specific names such as BOOL, Int32, Real, or DInt are rejected by the runtime.
Do I have to provide a default attribute on every <hmi:paramDef>?
It is strongly recommended. The runtime uses the default value when the parameter is not wired to a PLC tag or HMI tag. Omitting the default on numeric parameters can produce inconsistent behaviour between the editor preview and the runtime, and on some firmware versions it triggers a silent fallback to 0 or null.
Can I keep the SVG file as an external linked file instead of embedding it in the project library?
External linking works in the TIA Portal editor but typically fails on the runtime, because the runtime resolves widget paths relative to the project archive and does not follow arbitrary file system links. Use Project library → Save to embed the file in the project so the runtime can resolve the resource.
How do I force a clean reload of a custom widget on a real Unified Panel?
Stop the runtime, perform an Extended download to device → Replace project from TIA Portal, and restart the runtime from the Panel's Control Panel → Runtime → Restart dialog. The full project transfer clears the widget cache on the Panel and forces a fresh compile of every custom widget.