This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/struts-site.git
The following commit(s) were added to refs/heads/main by this push:
new 1abc30338 WW-5640 docs: document WebJars support (Struts 7.3.0) (#315)
1abc30338 is described below
commit 1abc30338b7f06f728a204ec043cbdf6c6bc1fe7
Author: Lukasz Lenart <[email protected]>
AuthorDate: Mon Jul 6 15:34:13 2026 +0200
WW-5640 docs: document WebJars support (Struts 7.3.0) (#315)
* WW-5640 docs: add webjar tag reference page
Document the new <s:webjar> tag (and <@s.webjar> macro) that resolves
version-less WebJar resource paths to servable URLs, introduced in
Struts 7.3.0. Pulls description/attributes from the released source and
links the Static Content serving pipeline. Lists the tag under Other
Tags in the tag reference index.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
* WW-5640 docs: document WebJars support in static content
Add a WebJars support section to the Static Content guide covering the
new /static/webjars/** serving pipeline, version-less resolution, the
struts.webjars.enabled and struts.webjars.allowlist constants, the
fail-closed security constraints, and the WebJarUrlProvider extension
seam. Introduced in Struts 7.3.0.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
---------
Co-authored-by: Claude Opus 4.8 <[email protected]>
---
source/core-developers/static-content.md | 65 ++++++++++++++++++++++++++++++++
source/tag-developers/tag-reference.md | 2 +-
source/tag-developers/webjar-tag.md | 51 +++++++++++++++++++++++++
3 files changed, 117 insertions(+), 1 deletion(-)
diff --git a/source/core-developers/static-content.md
b/source/core-developers/static-content.md
index 6d132577f..1416472ae 100644
--- a/source/core-developers/static-content.md
+++ b/source/core-developers/static-content.md
@@ -63,6 +63,71 @@ If needed you can change the default path at which static
content is served. Jus
This value is also used by the Default Content Loader.
+## WebJars support
+
+{:.alert .alert-info}
+Available since Struts 7.3.0.
+
+[WebJars](https://www.webjars.org/) package client-side libraries (Bootstrap,
jQuery, …) as JARs, shipping their assets
+under `META-INF/resources/webjars/<name>/<version>/…`. Instead of vendoring
these files into your web application and
+re-committing them on every upgrade, you add the WebJar as a regular
dependency and let Struts resolve and serve it.
+
+Struts serves WebJar assets through the same static content pipeline described
above, under
+`<staticContentPath>/webjars/**` (by default `/static/webjars/**`). Resolution
is **version-less**: you reference a
+resource by its logical path and Struts resolves the version present on the
classpath. For example, a request for:
+
+```
+/static/webjars/bootstrap/css/bootstrap.min.css
+```
+
+is served from
`META-INF/resources/webjars/bootstrap/5.3.8/css/bootstrap.min.css` (whichever
version is on the
+classpath). To emit these URLs from a template without hardcoding the version,
use the
+[webjar tag](../tag-developers/webjar-tag):
+
+```jsp
+<link rel="stylesheet" href="<s:webjar
path="bootstrap/css/bootstrap.min.css"/>"/>
+```
+
+Struts resolves versions using
[webjars-locator-lite](https://github.com/webjars/webjars-locator-lite), which
is bundled
+with `struts2-core`.
+
+### Configuration
+
+| Constant | Default | Description
|
+|----------------------------|---------|---------------------------------------------------------------------------------------------------|
+| `struts.webjars.enabled` | `true` | Master switch for resolving and
serving WebJar assets under `<staticContentPath>/webjars/**`. |
+| `struts.webjars.allowlist` | (empty) | Optional comma-separated allowlist of
WebJar names. When empty, all WebJars on the classpath are allowed. |
+
+To restrict serving to specific WebJars:
+
+```xml
+<constant name="struts.webjars.allowlist" value="bootstrap,jquery"/>
+```
+
+To disable the feature entirely:
+
+```xml
+<constant name="struts.webjars.enabled" value="false"/>
+```
+
+### Security
+
+Resolution is hard-constrained to the `META-INF/resources/webjars/` root: path
traversal attempts (`..`, `.`,
+backslashes) are rejected before resolution, the resolved path is re-checked
for containment, and only paths that the
+locator can resolve to a real WebJar are served. Disabled, unresolved,
traversal, and allowlist-blocked requests all
+**fail closed** - a `404` when serving and empty output when building URLs.
+
+### Customizing resolution
+
+URL resolution is provided by the
`org.apache.struts2.webjars.WebJarUrlProvider` container bean (default
implementation
+`DefaultWebJarUrlProvider`), which exposes `resolveResourcePath(String)` and
`resolveUrl(String, HttpServletRequest)`.
+Plugins and applications can replace it by declaring their own bean:
+
+```xml
+<bean type="org.apache.struts2.webjars.WebJarUrlProvider"
class="com.example.MyWebJarUrlProvider" name="myProvider"/>
+<constant name="struts.webjars.urlProvider" value="myProvider"/>
+```
+
## Preventing Struts from handling a request
If there is a request that Struts is handling as an action, and you wish to
make Struts ignore it,
diff --git a/source/tag-developers/tag-reference.md
b/source/tag-developers/tag-reference.md
index 32997e35c..8c00832ca 100644
--- a/source/tag-developers/tag-reference.md
+++ b/source/tag-developers/tag-reference.md
@@ -30,7 +30,7 @@ Struts Generic Tags control the execution flow as pages
render.
| [if](if-tag) | [a](a-tag) |
[compress](compress-tag) |
| [elseif](elseif-tag) | [action](action-tag) | [script](script-tag)
|
| [else](else-tag) | [bean](bean-tag) | [link](link-tag)
|
-| [append](append-tag) | [date](date-tag) |
|
+| [append](append-tag) | [date](date-tag) | [webjar](webjar-tag)
|
| [generator](generator-tag) | [debug](debug-tag) |
|
| [iterator](iterator-tag) | [i18n](i18n-tag) |
|
| [merge](merge-tag) | [include](include-tag) |
|
diff --git a/source/tag-developers/webjar-tag.md
b/source/tag-developers/webjar-tag.md
new file mode 100644
index 000000000..34df2faeb
--- /dev/null
+++ b/source/tag-developers/webjar-tag.md
@@ -0,0 +1,51 @@
+---
+layout: default
+title: webjar tag
+parent:
+ title: Tag Reference
+ url: tag-reference.html
+---
+
+# webjar
+
+{:.alert .alert-info}
+Available since Struts 7.3.0.
+
+Please make sure you have read the [Tag Syntax](tag-syntax) document and
understand how tag attribute syntax works.
+
+## Description
+
+Resolves a version-less [WebJar](https://www.webjars.org/) resource path to a
servable URL and writes it to the output
+(or stores it in a variable when `var` is set). For example,
`bootstrap/css/bootstrap.min.css` is resolved to
+`<ctx>/static/webjars/bootstrap/5.3.8/css/bootstrap.min.css`, so you never
hardcode the WebJar version in your templates.
+
+The tag emits a plain URL string, so it composes with [script](script-tag),
[link](link-tag), or a raw `<link>` /
+`<script>` element. See [Static
Content](../core-developers/static-content#webjars-support) for the serving
pipeline and
+configuration constants.
+
+{% remote_file_content
https://raw.githubusercontent.com/apache/struts/main/core/src/site/resources/tags/webjar-description.html
%}
+
+## Attributes
+
+{% remote_file_content
https://raw.githubusercontent.com/apache/struts/main/core/src/site/resources/tags/webjar-attributes.html
%}
+
+## Examples
+
+**Example 1** - reference a WebJar stylesheet:
+
+```jsp
+<link rel="stylesheet" href="<s:webjar
path="bootstrap/css/bootstrap.min.css"/>"/>
+```
+
+**Example 2** - reference a WebJar script:
+
+```jsp
+<s:webjar var="webjarUrl" path="jquery/jquery.min.js"/>
+<s:script src="%{webjarUrl}"/>
+```
+
+**Example 3** - FreeMarker macro:
+
+```html
+<@s.webjar path="jquery/jquery.min.js"/>
+```