{"id":9736,"date":"2025-05-30T15:25:00","date_gmt":"2025-05-30T12:25:00","guid":{"rendered":"https:\/\/handoli.com\/index.php\/2025\/05\/30\/tips-and-tricks-for-when-using-swiftuis-viewbuilder\/"},"modified":"2025-05-30T15:25:00","modified_gmt":"2025-05-30T12:25:00","slug":"tips-and-tricks-for-when-using-swiftuis-viewbuilder","status":"publish","type":"post","link":"https:\/\/handoli.com\/index.php\/2025\/05\/30\/tips-and-tricks-for-when-using-swiftuis-viewbuilder\/","title":{"rendered":"Tips and tricks for when using SwiftUI\u2019s ViewBuilder"},"content":{"rendered":"<p>SwiftUI\u2019s <code>ViewBuilder<\/code> type is a key part of the library\u2019s overall API design, in that it\u2019s what enables multiple view expressions to be declared within a given scope (such as a <code>body<\/code> property implementation, or a closure passed to containers such as <code>HStack<\/code> or <code>VStack<\/code>) without requiring any manual grouping or wrapping at each call site.<\/p>\n<p>For example, within the following <code>VStack<\/code>, we can simply place each subview within the closure we pass to it, and <code>ViewBuilder<\/code> will take care of collecting those views and <em>building<\/em> them into the final content that then gets rendered within the stack:<\/p>\n<pre class=\"splash\"><code><span class=\"s-type\">VStack<\/span> {\n    <span class=\"s-type\">Image<\/span>(systemName: <span class=\"s-string\">\"star\"<\/span>)\n    <span class=\"s-type\">Text<\/span>(<span class=\"s-string\">\"Hello, world!\"<\/span>)\n}<\/code><\/pre>\n<p>What\u2019s interesting about <code>ViewBuilder<\/code> is that it\u2019s completely possible to use SwiftUI for a significant amount of time before even discovering that it exists. After all, we don\u2019t have to reference it explicitly in most situations, as SwiftUI\u2019s various closures and protocols have already been annotated with the corresponding <code>@ViewBuilder<\/code> attribute out of the box.<\/p>\n<p>For example, the <code>View<\/code> protocol that we use every time we want to define a custom view uses <code>ViewBuilder<\/code> implicitly, since the definition for the <code>body<\/code> property requirement looks like this:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">@MainActor @preconcurrency public protocol<\/span> View {\n    <span class=\"s-keyword\">associatedtype<\/span> Body : <span class=\"s-type\">View<\/span>\n\n    <span class=\"s-keyword\">@ViewBuilder<\/span> <span class=\"s-keyword\">@MainActor @preconcurrency var<\/span> body: <span class=\"s-type\">Self<\/span>.<span class=\"s-type\">Body<\/span> { <span class=\"s-keyword\">get<\/span> }\n}<\/code><\/pre>\n<p>That\u2019s what makes it possible to use things like control flow within our view <code>body<\/code> implementations, even when each branch within such a flow returns different types, and even when we don\u2019t explicitly mark our property with <code>@ViewBuilder<\/code> ourselves:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">struct<\/span> RootView: <span class=\"s-type\">View<\/span> {\n    <span class=\"s-keyword\">@State private var<\/span> user: <span class=\"s-type\">User<\/span>?\n\n    <span class=\"s-keyword\">var<\/span> body: <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        <span class=\"s-keyword\">if let<\/span> user {\n            <span class=\"s-type\">HomeView<\/span>(user: user)\n        } <span class=\"s-keyword\">else<\/span> {\n            <span class=\"s-type\">LoginView<\/span>(user: <span class=\"s-property\">$user<\/span>)\n        }\n    }\n}<\/code><\/pre>\n<blockquote>\n<p>The way our views automatically get annotated with <code>@ViewBuilder<\/code> works the same way as why we don\u2019t have to manually mark our views as <code>@MainActor<\/code> to run them on the main thread \u2014 our custom view types automatically inherit those attributes from the <code>View<\/code> protocol declaration.<\/p>\n<\/blockquote>\n<p>But there <em>are<\/em> situations in which using <code>ViewBuilder<\/code> directly can be incredibly useful \u2014 so let\u2019s go ahead and explore a few such examples, along with some tips and tricks that can be good to keep in mind when writing that kind of code.<\/p>\n<h2>Custom containers<\/h2>\n<p>Any property, function, or closure can be marked with the <code>@ViewBuilder<\/code> attribute, which opts that code into getting the same <em><a href=\"https:\/\/en.wikipedia.org\/wiki\/Domain-specific_language\">\u201cDSL-like\u201d<\/a><\/em> capabilities as SwiftUI\u2019s built-in APIs. For example, let\u2019s say that we\u2019re building a custom <code>Container<\/code> view, which renders a <code>header<\/code> on top of a <code>content<\/code> view, while also applying some default styling to those two components:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">struct<\/span> Container&lt;Header: <span class=\"s-type\">View<\/span>, Content: <span class=\"s-type\">View<\/span>&gt;: <span class=\"s-type\">View<\/span> {\n    <span class=\"s-keyword\">var<\/span> header: <span class=\"s-type\">Header<\/span>\n    <span class=\"s-keyword\">var<\/span> content: <span class=\"s-type\">Content<\/span>\n\n    <span class=\"s-keyword\">var<\/span> body: <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        <span class=\"s-type\">VStack<\/span>(spacing: <span class=\"s-number\">0<\/span>) {\n            header\n                .<span class=\"s-call\">frame<\/span>(maxWidth: .<span class=\"s-dotAccess\">infinity<\/span>)\n                .<span class=\"s-call\">padding<\/span>()\n                .<span class=\"s-call\">foregroundStyle<\/span>(.<span class=\"s-dotAccess\">white<\/span>)\n                .<span class=\"s-call\">background<\/span>(<span class=\"s-type\">Color<\/span>.<span class=\"s-property\">blue<\/span>)\n\n            <span class=\"s-type\">ScrollView<\/span> {\n                content.<span class=\"s-call\">padding<\/span>()\n            }\n        }\n    }\n}<\/code><\/pre>\n<p>As our <code>Container<\/code> view is currently defined, we\u2019re limited to using just a single view for both the <code>header<\/code> and <code>content<\/code> properties, and we\u2019d pass them just like we\u2019d pass any other Swift initializer values \u2014 for example like this:<\/p>\n<pre class=\"splash\"><code><span class=\"s-type\">Container<\/span>(header: <span class=\"s-type\">Text<\/span>(<span class=\"s-string\">\"Welcome\"<\/span>), content: <span class=\"s-type\">ContentView<\/span>())<\/code><\/pre>\n<p>Now, let\u2019s go ahead and mark both <code>header<\/code> and <code>content<\/code> with the <code>@ViewBuilder<\/code> attribute, to see how that affects our view\u2019s API:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">struct<\/span> Container&lt;Header: <span class=\"s-type\">View<\/span>, Content: <span class=\"s-type\">View<\/span>&gt;: <span class=\"s-type\">View<\/span> {\n    <span class=\"s-keyword\">@ViewBuilder<\/span> <span class=\"s-keyword\">var<\/span> header: <span class=\"s-type\">Header<\/span>\n    <span class=\"s-keyword\">@ViewBuilder<\/span> <span class=\"s-keyword\">var<\/span> content: <span class=\"s-type\">Content<\/span>\n\n    <span class=\"s-keyword\">var<\/span> body: <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        ...\n    }\n}<\/code><\/pre>\n<p>What\u2019s interesting is that, even though we haven\u2019t redefined either of the above properties as being closures (they still both just store a single view value), their values must now be <em>passed<\/em> as closures when we initialize our <code>Container<\/code> view. <code>ViewBuilder<\/code> will then take any closure that we passed, and apply its view building logic to it, resulting in a single output view, which is then stored within each property.<\/p>\n<p>What that means is that we\u2019re now able to use the same SwiftUI syntax as when interacting with the library\u2019s built-in APIs when defining either our <code>header<\/code> or <code>content<\/code>. Let\u2019s use that new capability to update our <code>RootView<\/code> from before to use our new <code>Container<\/code> implementation, as we\u2019re now able to use an <code>if<\/code> statement with separate view branches to declare our view\u2019s <code>content<\/code>:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">struct<\/span> RootView: <span class=\"s-type\">View<\/span> {\n    <span class=\"s-keyword\">@State private var<\/span> user: <span class=\"s-type\">User<\/span>?\n\n    <span class=\"s-keyword\">var<\/span> body: <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        <span class=\"s-type\">Container<\/span>(header: {\n            <span class=\"s-type\">Text<\/span>(<span class=\"s-string\">\"Welcome\"<\/span>)\n        }, content: {\n            <span class=\"s-keyword\">if let<\/span> user {\n                <span class=\"s-type\">HomeView<\/span>(user: user)\n            } <span class=\"s-keyword\">else<\/span> {\n                <span class=\"s-type\">LoginView<\/span>(user: <span class=\"s-property\">$user<\/span>)\n            }\n        })\n    }\n}<\/code><\/pre>\n<p>Neat! Next, let\u2019s take a look at how we might handle situations when we want to omit a specific component from a custom container view.<\/p>\n<h2>Making view builder properties optional<\/h2>\n<p>For example, let\u2019s say that we want to make our <code>Container<\/code> view\u2019s <code>header<\/code> optional. One way to get that done would be to write an extension on <code>Container<\/code> with a generic constraint on SwiftUI\u2019s <code>EmptyView<\/code> type, which allows us to then pass that type\u2019s initializer as a closure when calling our view\u2019s member-wise initializer:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">extension<\/span> <span class=\"s-type\">Container<\/span> <span class=\"s-keyword\">where<\/span> <span class=\"s-type\">Header<\/span> == <span class=\"s-type\">EmptyView<\/span> {\n    <span class=\"s-keyword\">init<\/span>(<span class=\"s-keyword\">@ViewBuilder<\/span> content: () -&gt; <span class=\"s-type\">Content<\/span>) {\n        <span class=\"s-keyword\">self<\/span>.<span class=\"s-keyword\">init<\/span>(header: <span class=\"s-type\">EmptyView<\/span>.<span class=\"s-keyword\">init<\/span>, content: content)\n    }\n}<\/code><\/pre>\n<p>Note that we have to use a closure for our <code>content<\/code> property above, rather than just a <code>Content<\/code> value. That\u2019s because the automatic conversion from view builder closure to single view value that we utilized before only works for stored properties, not for function arguments. Our closure doesn\u2019t need to be <code>@escaping<\/code>, though, since SwiftUI will still evaluate it directly and automatically convert it into a single view, just like when using our view\u2019s member-wise initializer.<\/p>\n<p>With the above in place, we could now update our <code>RootView<\/code> to no longer use a header, which in turn enables us to use trailing closure syntax to achieve a call site that looks exactly like when using SwiftUI\u2019s built in containers (like <code>HStack<\/code> or <code>VStack<\/code>):<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">struct<\/span> RootView: <span class=\"s-type\">View<\/span> {\n    <span class=\"s-keyword\">@State private var<\/span> user: <span class=\"s-type\">User<\/span>?\n\n    <span class=\"s-keyword\">var<\/span> body: <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        <span class=\"s-type\">Container<\/span> {\n            <span class=\"s-keyword\">if let<\/span> user {\n                <span class=\"s-type\">HomeView<\/span>(user: user)\n            } <span class=\"s-keyword\">else<\/span> {\n                <span class=\"s-type\">LoginView<\/span>(user: <span class=\"s-property\">$user<\/span>)\n            }\n        }\n    }\n}<\/code><\/pre>\n<p>While the above works great, there\u2019s an alternative approach that we can take if we don\u2019t want to define a constrained <code>Container<\/code> extension, but rather just use a custom initializer with default argument values instead.<\/p>\n<p>What\u2019s cool about using <code>ViewBuilder<\/code> is that, unlike when accepting separate view values directly, the compiler will automatically infer the concrete types for <code>Header<\/code> and <code>Content<\/code> if we use default arguments for their corresponding values.<\/p>\n<p>So, if we specify <code>EmptyView.init<\/code> as the default value for our <code>header<\/code> property argument, then we can achieve the exact same result as when using the extension-based approach, while also giving us the option to keep adding more default values and convenience APIs in the future \u2014 all without having to define multiple extensions:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">struct<\/span> Container&lt;Header: <span class=\"s-type\">View<\/span>, Content: <span class=\"s-type\">View<\/span>&gt;: <span class=\"s-type\">View<\/span> {\n    <span class=\"s-keyword\">var<\/span> header: <span class=\"s-type\">Header<\/span>\n    <span class=\"s-keyword\">var<\/span> content: <span class=\"s-type\">Content<\/span>\n\n    <span class=\"s-keyword\">init<\/span>(<span class=\"s-keyword\">@ViewBuilder<\/span> header: () -&gt; <span class=\"s-type\">Header<\/span> = <span class=\"s-type\">EmptyView<\/span>.<span class=\"s-keyword\">init<\/span>,\n         <span class=\"s-keyword\">@ViewBuilder<\/span> content: () -&gt; <span class=\"s-type\">Content<\/span>) {\n        <span class=\"s-keyword\">self<\/span>.<span class=\"s-property\">header<\/span> = <span class=\"s-call\">header<\/span>()\n        <span class=\"s-keyword\">self<\/span>.<span class=\"s-property\">content<\/span> = <span class=\"s-call\">content<\/span>()\n    }\n\n    <span class=\"s-keyword\">var<\/span> body: <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        ...\n    }\n}<\/code><\/pre>\n<p>Note that we no longer need to add the <code>@ViewBuilder<\/code> attribute to our properties, since we now perform the closure-to-view conversion ourselves (by simply calling those closures within our view\u2019s initializer).<\/p>\n<p>An alternative approach would\u2019ve been to instead store references to our closures within the <code>header<\/code> and <code>content<\/code> properties, and to then call those closures within our view\u2019s <code>body<\/code>. Doing so wouldn\u2019t make much of a difference in this particular case (besides requiring those closures to be <code>@escaping<\/code>, which most of SwiftUI\u2019s own view builder closures aren\u2019t), however, in some situations, taking that approach can significantly hurt performance \u2014 since we\u2019ll end up re-evaluating those closures every time our view\u2019s <code>body<\/code> gets re-evaluated. So, when possible, resolving each view builder closure up-front gives us the most predictable and consistent results.<\/p>\n<h2>Handling multiple view expressions<\/h2>\n<p>Just like when using SwiftUI\u2019s built-in containers, it\u2019s also now possible to place multiple view expressions within either our <code>header<\/code> or <code>content<\/code> closures. For example, if we bring back the header within our <code>RootView<\/code>, we might use this capability to add a <code>NavigationLink<\/code> below our welcome text \u2014 like this:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">struct<\/span> RootView: <span class=\"s-type\">View<\/span> {\n    ...\n\n    <span class=\"s-keyword\">var<\/span> body: <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        <span class=\"s-type\">Container<\/span>(header: {\n            <span class=\"s-type\">Text<\/span>(<span class=\"s-string\">\"Welcome\"<\/span>)\n            <span class=\"s-type\">NavigationLink<\/span>(<span class=\"s-string\">\"Info\"<\/span>) {\n                <span class=\"s-type\">InfoView<\/span>()\n            }\n        }, content: {\n            ...\n        })\n    }\n}<\/code><\/pre>\n<p>However, call sites like the one above might not always produce the result we\u2019d expect, since when processed by <code>ViewBuilder<\/code>, multiple view expressions will essentially be treated the same way as if they were added to a SwiftUI <code>Group<\/code> \u2014 in that they\u2019ll each be independently styled, sized, and positioned according to the current context.<\/p>\n<p>So, in the above example, we\u2019re not actually adding a <em>combined header<\/em> to our view, but rather <em>two separate headers<\/em> \u2014 each with its own layout within the enclosing <code>VStack<\/code>, and each with its own set of modifiers applied to it.<\/p>\n<p>To resolve that, it might be a good idea to wrap both our <code>header<\/code> and <code>content<\/code> views within explicit containers, so that their layout will always be predictable, even when multiple view expressions are used at a specific call site:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">struct<\/span> Container&lt;Header: <span class=\"s-type\">View<\/span>, Content: <span class=\"s-type\">View<\/span>&gt;: <span class=\"s-type\">View<\/span> {\n    ...\n\n    <span class=\"s-keyword\">var<\/span> body: <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        <span class=\"s-type\">VStack<\/span>(spacing: <span class=\"s-number\">0<\/span>) {\n            <span class=\"s-type\">VStack<\/span> { header }\n                .<span class=\"s-call\">frame<\/span>(maxWidth: .<span class=\"s-dotAccess\">infinity<\/span>)\n                .<span class=\"s-call\">padding<\/span>()\n                .<span class=\"s-call\">foregroundStyle<\/span>(.<span class=\"s-dotAccess\">white<\/span>)\n                .<span class=\"s-call\">background<\/span>(<span class=\"s-type\">Color<\/span>.<span class=\"s-property\">blue<\/span>)\n\n            <span class=\"s-type\">ScrollView<\/span> {\n                <span class=\"s-type\">VStack<\/span> { content }\n                    .<span class=\"s-call\">padding<\/span>()\n            }\n        }\n    }\n}<\/code><\/pre>\n<p>Whether to take the above approach (and enforce a specific layout within the container in question), or leave it up to each call site to define its own layout, will likely come down to a combination of personal\/team preference and the specific container (and layout behaviors) that we\u2019re implementing.<\/p>\n<p>There are cases, though, where it\u2019s arguably best to add an explicit container at the call site, in order to make our code more clear and easier to maintain. For example, here we\u2019re using <code>@ViewBuilder<\/code> as a sort of code organization tool, in that we\u2019re applying it to private functions that we\u2019re using to build separate parts of our view \u2014 which in general is a really great way to structure increasingly complex SwiftUI view implementations, rather than allowing our <code>body<\/code> properties to grow too large in scope:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">struct<\/span> RootView: <span class=\"s-type\">View<\/span> {\n    <span class=\"s-keyword\">@State private var<\/span> user: <span class=\"s-type\">User<\/span>?\n\n    <span class=\"s-keyword\">var<\/span> body: <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        <span class=\"s-type\">Container<\/span>(header: header, content: content)\n    }\n}\n\n<span class=\"s-keyword\">private extension<\/span> <span class=\"s-type\">RootView<\/span> {\n    <span class=\"s-keyword\">@ViewBuilder func<\/span> header() -&gt; <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        <span class=\"s-type\">Text<\/span>(<span class=\"s-string\">\"Welcome\"<\/span>)\n        <span class=\"s-type\">NavigationLink<\/span>(<span class=\"s-string\">\"Info\"<\/span>) {\n            <span class=\"s-type\">InfoView<\/span>()\n        }\n    }\n\n    <span class=\"s-keyword\">@ViewBuilder func<\/span> content() -&gt; <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        <span class=\"s-keyword\">if let<\/span> user {\n            <span class=\"s-type\">HomeView<\/span>(user: user)\n        } <span class=\"s-keyword\">else<\/span> {\n            <span class=\"s-type\">LoginView<\/span>(user: <span class=\"s-property\">$user<\/span>)\n        }\n    }\n}<\/code><\/pre>\n<p>However, while our above code is now very neatly organized, the semantics of our new <code>header<\/code> function are arguably a bit odd \u2014 since it doesn\u2019t really return <em>a header<\/em>, but rather multiple view expressions that will be <em>built into a header<\/em>. It might be a nitpicky detail in the grand scheme of things, but aiming to write code to be as clear as possible does often really help when it comes to future maintainability.<\/p>\n<p>A rule of thumb that can be good to follow is that a function or computed property should never return multiple root view expressions (since that gives us an implicit group, just like before). Instead, it would arguably be better if our <code>header<\/code> function didn\u2019t actually use <code>ViewBuilder<\/code>, but rather just returned an explicit <code>VStack<\/code> which in turn contains our header view\u2019s content. That way, it\u2019ll become crystal clear how our header will be rendered, even if we end up changing how our <code>Container<\/code> view works in the future:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">private extension<\/span> <span class=\"s-type\">RootView<\/span> {\n    <span class=\"s-keyword\">func<\/span> header() -&gt; <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        <span class=\"s-type\">VStack<\/span>(spacing: <span class=\"s-number\">20<\/span>) {\n            <span class=\"s-type\">Text<\/span>(<span class=\"s-string\">\"Welcome\"<\/span>)\n            <span class=\"s-type\">NavigationLink<\/span>(<span class=\"s-string\">\"Info\"<\/span>) {\n                <span class=\"s-type\">InfoView<\/span>()\n            }\n        }\n    }\n\n    <span class=\"s-keyword\">@ViewBuilder func<\/span> content() -&gt; <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        <span class=\"s-keyword\">if let<\/span> user {\n            <span class=\"s-type\">HomeView<\/span>(user: user)\n        } <span class=\"s-keyword\">else<\/span> {\n            <span class=\"s-type\">LoginView<\/span>(user: <span class=\"s-property\">$user<\/span>)\n        }\n    }\n}<\/code><\/pre>\n<p>We still want to keep using <code>@ViewBuilder<\/code> for our <code>content<\/code> function, though, since it returns just a single (albeit conditional) root view expression.<\/p>\n<h2>Conclusion<\/h2>\n<p>SwiftUI\u2019s <code>ViewBuilder<\/code> is a really powerful tool, and the fact that we can opt our own code into using it gives us a lot of flexibility when it comes to how we want to structure and reuse our UI code. By adopting it within our own custom containers, we can really craft APIs that feel right at home alongside SwiftUI\u2019s own features, which in turn should help us improve the consistency and clarity of the UI code that we write.<\/p>\n<p>I hope you enjoyed this article. If you have any questions, comments, or feedback, then feel free to reach out via either <a href=\"https:\/\/mastodon.social\/@johnsundell\">Mastodon<\/a> or <a href=\"https:\/\/bsky.app\/profile\/johnsundell.bsky.social\">Bluesky<\/a>.<\/p>\n<p>Thanks for reading!<\/p>","protected":false},"excerpt":{"rendered":"<p>SwiftUI\u2019s ViewBuilder type is a key part of the library\u2019s overall API design, in that it\u2019s what enables multiple view expressions to be declared within a given scope (such as a body property implementation, or a closure passed to containers such as HStack or VStack) without requiring any manual grouping or wrapping at each call [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"rop_custom_images_group":[],"rop_custom_messages_group":[],"rop_publish_now":"initial","rop_publish_now_accounts":[],"rop_publish_now_history":[],"rop_publish_now_status":"pending","footnotes":""},"categories":[1,15],"tags":[],"class_list":["post-9736","post","type-post","status-publish","format-standard","hentry","category-explore","category-world"],"_links":{"self":[{"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/posts\/9736","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/comments?post=9736"}],"version-history":[{"count":0,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/posts\/9736\/revisions"}],"wp:attachment":[{"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/media?parent=9736"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/categories?post=9736"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/tags?post=9736"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}