diff --git a/.changes/next-release/feature-3c70351cce599e85b810d4418fee8e5ca661436e.json b/.changes/next-release/feature-3c70351cce599e85b810d4418fee8e5ca661436e.json
new file mode 100644
index 00000000000..6ee989999f4
--- /dev/null
+++ b/.changes/next-release/feature-3c70351cce599e85b810d4418fee8e5ca661436e.json
@@ -0,0 +1,7 @@
+{
+ "type": "feature",
+ "description": "Updated smithy-docgen to consume snippet files to generate example sections.",
+ "pull_requests": [
+ "[#2894](https://github.com/smithy-lang/smithy/pull/2894)"
+ ]
+}
diff --git a/.changes/next-release/feature-df6f8fb30971b29b76010e7143df11affcb9618f.json b/.changes/next-release/feature-df6f8fb30971b29b76010e7143df11affcb9618f.json
new file mode 100644
index 00000000000..0f5c9ae8773
--- /dev/null
+++ b/.changes/next-release/feature-df6f8fb30971b29b76010e7143df11affcb9618f.json
@@ -0,0 +1,7 @@
+{
+ "type": "feature",
+ "description": "Added a `SnippetConfig` class to codgen-core that allows sharing doc snippets that will be consumed by smithy-docgen.",
+ "pull_requests": [
+ "[#2894](https://github.com/smithy-lang/smithy/pull/2894)"
+ ]
+}
diff --git a/.changes/next-release/feature-e6e564588167f70492cf365c0663ba0b17f0a3d8.json b/.changes/next-release/feature-e6e564588167f70492cf365c0663ba0b17f0a3d8.json
new file mode 100644
index 00000000000..193a8451956
--- /dev/null
+++ b/.changes/next-release/feature-e6e564588167f70492cf365c0663ba0b17f0a3d8.json
@@ -0,0 +1,7 @@
+{
+ "type": "feature",
+ "description": "Made `DefaultBuilderRef` public.",
+ "pull_requests": [
+ "[#2894](https://github.com/smithy-lang/smithy/pull/2894)"
+ ]
+}
diff --git a/smithy-codegen-core/src/main/java/software/amazon/smithy/codegen/core/docs/Snippet.java b/smithy-codegen-core/src/main/java/software/amazon/smithy/codegen/core/docs/Snippet.java
new file mode 100644
index 00000000000..b91dce7d723
--- /dev/null
+++ b/smithy-codegen-core/src/main/java/software/amazon/smithy/codegen/core/docs/Snippet.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package software.amazon.smithy.codegen.core.docs;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import software.amazon.smithy.model.shapes.ShapeId;
+import software.amazon.smithy.utils.BuilderRef;
+import software.amazon.smithy.utils.SmithyBuilder;
+import software.amazon.smithy.utils.SmithyUnstableApi;
+import software.amazon.smithy.utils.StringUtils;
+import software.amazon.smithy.utils.ToSmithyBuilder;
+
+/**
+ * Represents a generated snippet, potentially containing multiple logical files.
+ *
+ *
Snippets are generated code based on some trait or other shared definition,
+ * such as the {@link software.amazon.smithy.model.traits.ExamplesTrait}. These are
+ * created by code generators and consumed by documentation tools, such as
+ * smithy-docgen.
+ */
+@SmithyUnstableApi
+public final class Snippet implements ToSmithyBuilder {
+ private final String targetId;
+ private final String title;
+ private final ShapeId protocol;
+ private final List files;
+
+ private Snippet(Builder builder) {
+ this.targetId = SmithyBuilder.requiredState("targetId", builder.targetId);
+ if (StringUtils.isBlank(targetId)) {
+ throw new IllegalStateException("Snippet target id must not be blank");
+ }
+ this.title = SmithyBuilder.requiredState("title", builder.title);
+ if (StringUtils.isBlank(title)) {
+ throw new IllegalStateException("Snippet title must not be blank");
+ }
+ this.protocol = builder.protocol;
+ this.files = builder.files.copy();
+ if (this.files.isEmpty()) {
+ throw new IllegalStateException("Snippets must contain at least one file");
+ }
+ }
+
+ /**
+ * Gets the identifier of what the snippet was generated for.
+ *
+ * If this snippet represents a generated example from the
+ * {@link software.amazon.smithy.model.traits.ExamplesTrait}, this
+ * will be the title of the example.
+ *
+ * @return Returns the target identifier of the snippet.
+ */
+ public String getTargetId() {
+ return targetId;
+ }
+
+ /**
+ * Gets the title of the snippet.
+ *
+ *
This is distinct from the target ID as it identifies the specific snippet.
+ *
+ *
Generally, the title should reflect the primary language of the snippet,
+ * such as "Python" for a Python snippet.
+ *
+ * @return Returns the title of the snippet.
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * @return Optionally returns the ShapeId of the protocol associated with this snippet.
+ */
+ public Optional getProtocol() {
+ return Optional.ofNullable(protocol);
+ }
+
+ /**
+ * @return Returns the files that comprise the snippet.
+ */
+ public List getFiles() {
+ return files;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof Snippet)) {
+ return false;
+ }
+ Snippet snippet = (Snippet) o;
+ return Objects.equals(targetId, snippet.targetId)
+ && Objects.equals(protocol, snippet.protocol)
+ && Objects.equals(files, snippet.files);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(targetId, protocol, files);
+ }
+
+ @Override
+ public Builder toBuilder() {
+ return builder()
+ .targetId(targetId)
+ .protocol(protocol)
+ .files(files);
+ }
+
+ /**
+ * @return Returns a new Snippet builder.
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder implements SmithyBuilder {
+ private String targetId;
+ private String title;
+ private ShapeId protocol;
+ private final BuilderRef> files = BuilderRef.forList();
+
+ @Override
+ public Snippet build() {
+ return new Snippet(this);
+ }
+
+ /**
+ * Sets the target id of the snippet.
+ *
+ * @param id The id to set as the target of the snippet.
+ * @return Returns the builder.
+ */
+ public Builder targetId(String id) {
+ this.targetId = id;
+ return this;
+ }
+
+ /**
+ * Sets the title of the snippet.
+ *
+ * @param title The title to set for the snippet.
+ * @return Returns the builder.
+ */
+ public Builder title(String title) {
+ this.title = title;
+ return this;
+ }
+
+ /**
+ * Sets the protocol of the snippet.
+ *
+ * To remove the protocol, set a null value.
+ *
+ * @param protocol The shape id of the protocol the snippet is tied to.
+ * @return Returns the builder.
+ */
+ public Builder protocol(ShapeId protocol) {
+ this.protocol = protocol;
+ return this;
+ }
+
+ /**
+ * Sets the files that make up the snippet.
+ *
+ * @param files A list of files that make up the snippet.
+ * @return Returns the builder.
+ */
+ public Builder files(Collection files) {
+ this.files.clear();
+ this.files.get().addAll(files);
+ return this;
+ }
+
+ /**
+ * Adds a file to the snippet.
+ *
+ * @param file A file to add to the snippet.
+ * @return Returns the builder.
+ */
+ public Builder addFile(SnippetFile file) {
+ this.files.get().add(file);
+ return this;
+ }
+ }
+}
diff --git a/smithy-codegen-core/src/main/java/software/amazon/smithy/codegen/core/docs/SnippetConfig.java b/smithy-codegen-core/src/main/java/software/amazon/smithy/codegen/core/docs/SnippetConfig.java
new file mode 100644
index 00000000000..b68a9c0e112
--- /dev/null
+++ b/smithy-codegen-core/src/main/java/software/amazon/smithy/codegen/core/docs/SnippetConfig.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package software.amazon.smithy.codegen.core.docs;
+
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+import software.amazon.smithy.model.node.Node;
+import software.amazon.smithy.model.node.NodeMapper;
+import software.amazon.smithy.model.node.ObjectNode;
+import software.amazon.smithy.model.node.ToNode;
+import software.amazon.smithy.model.shapes.ShapeId;
+import software.amazon.smithy.utils.BuilderRef;
+import software.amazon.smithy.utils.DefaultBuilderRef;
+import software.amazon.smithy.utils.IoUtils;
+import software.amazon.smithy.utils.ListUtils;
+import software.amazon.smithy.utils.MapUtils;
+import software.amazon.smithy.utils.SmithyBuilder;
+import software.amazon.smithy.utils.SmithyUnstableApi;
+import software.amazon.smithy.utils.ToSmithyBuilder;
+
+/**
+ * Represents a file containing generated snippets.
+ *
+ * Snippets are generated code based on some trait or other shared definition,
+ * such as the {@link software.amazon.smithy.model.traits.ExamplesTrait}. These are
+ * created by code generators and consumed by documentation tools, such as
+ * smithy-docgen.
+ *
+ *
These are differentiated from typical code gen artifacts in that they are
+ * intended to be shared. These may be distributed and aggregated in any manner,
+ * but they SHOULD be written to the {@literal snippets} directory of the shared
+ * plugin space by Smithy build plugins. smithy-docgen will discover and include
+ * any snippet files in that directory. Smithy build plugins MUST declare a
+ * {@code runBefore} on "docgen" for their generated snippets to be included.
+ */
+@SmithyUnstableApi
+public final class SnippetConfig implements ToSmithyBuilder, ToNode {
+ public static final String DEFAULT_VERSION = "1.0";
+
+ private final String version;
+ private final Map>> snippets;
+
+ private SnippetConfig(Builder builder) {
+ this.version = SmithyBuilder.requiredState("version", builder.version);
+ this.snippets = builder.snippets.copy();
+ }
+
+ /**
+ * @return Returns the version of the snippet config.
+ */
+ public String getVersion() {
+ return version;
+ }
+
+ /**
+ * @return Returns all the snippets in the config.
+ */
+ public Map>> getSnippets() {
+ return snippets;
+ }
+
+ /**
+ * Gets all the snippets for a particular service.
+ *
+ * @param id The id of the service to get snippets for.
+ * @return Returns the snippets for shapes bound to the service.
+ */
+ public Map> getServiceSnippets(ShapeId id) {
+ return snippets.getOrDefault(id, Collections.emptyMap());
+ }
+
+ /**
+ * Gets the snippets for a particular shape in a service.
+ *
+ * @param serviceId The service to search for snippets.
+ * @param shapeId The shape to get snippets for.
+ * @return Returns the snippets for a shape from a service.
+ */
+ public List getShapeSnippets(ShapeId serviceId, ShapeId shapeId) {
+ return getServiceSnippets(serviceId).getOrDefault(shapeId, Collections.emptyList());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof SnippetConfig)) {
+ return false;
+ }
+ SnippetConfig config = (SnippetConfig) o;
+ return Objects.equals(version, config.version) && Objects.equals(snippets, config.snippets);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(version, snippets);
+ }
+
+ @Override
+ public Builder toBuilder() {
+ return builder()
+ .version(version)
+ .snippets(snippets);
+ }
+
+ /**
+ * @return Returns a new SnippetConfig builder.
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public Node toNode() {
+ return ObjectNode.objectNodeBuilder()
+ .withMember("version", version)
+ .withMember("snippets", new NodeMapper().serialize(snippets))
+ .build();
+ }
+
+ /**
+ * @param node A node representing a SnippetConfig.
+ * @return Returns a SnippetConfig based on the given node.
+ */
+ public static SnippetConfig fromNode(Node node) {
+ Builder builder = builder();
+ new NodeMapper().deserializeInto(node, builder);
+ return builder.build();
+ }
+
+ /**
+ * Loads a SnippetConfig from a JSON file.
+ *
+ * @param path The path to the JSON snippet config.
+ * @return Returns a SnippetConfig based on the given file.
+ */
+ public static SnippetConfig load(Path path) {
+ return fromNode(Node.parse(IoUtils.readUtf8File(path)));
+ }
+
+ public final static class Builder implements SmithyBuilder {
+ private String version = DEFAULT_VERSION;
+ private final BuilderRef