The best way to allow optional parameter for a fragment is to declare them with "th:with" and describe them with meaningful default values.
So, you define explicit your mandatory and your optional values in the declaration tag of your fragment.
Here is simple example, with 1 mandatory and 2 optional parameters:
<div th:fragment="printGreetings (name)" th:with="title=${title} ?: 'Mr.', greeting=${greeting} ?: 'Hello'">
<span th:text="${greeting}">Hello</span>
<span th:text="${title}">Mr.</span>
<span th:text="${name}">John Doe</span>
</div>
You can then call it like the following:
<div th:replace="fragments :: printGreetings (name='daniel')">
Hello Mr. Daniel
</div>
<div th:replace="fragments :: printGreetings (name='Lea', title='Ms.')>
Hello Ms. Lea
</div>
<div th:replace="fragments :: printGreetings (name='Lea', title='Ms.', greeting='Hi')>
Hi Ms. Lea
</div>
(Please note that all values inside the tags are replaced by the dynamic ones. It's just for better reading.)