I personally found that adding structured data was best done at theme level and built specifically from the ground up. For example we introduced event schema markup. We originally went for microdata markup (using itemProp inline for example).
However after implementation we found that microdata wasn’t indexed as effectively as JSON-LD schema data, example: https://developers.google.com/search/docs/data-types/event. Also microdata and inline schema markup really bloated template files, and slowed down development.
We also tried a few plugins in a bid to save time. But after not much success due to the amount of custom data we have, we quickly converted to custom JSON-LD markup. It was really easy to implement and indexing is almost instantaneous with Google.
This is handy for testing: https://search.google.com/structured-data/testing-tool/u/0/
In terms of Sage, you can use the
@stack directive and
@push directive to push data through
json_encode from within any template partial - generally when you’re looping through your data to output it as you normally would. We then output that stack in the head of the document. So long as you configure your data array to have the JSON-LD keys that Google suggests it’s fairly straight forward.
The one caveat of this approach is that it’s a developer implementation and not something with a front end