diff --git a/.version b/.version
index 8b55513d7..54af2b630 100644
--- a/.version
+++ b/.version
@@ -1 +1 @@
-0.2.499
\ No newline at end of file
+0.2.500
\ No newline at end of file
diff --git a/docs/docs/03-syntax-and-usage/14-using-with-go-templates.md b/docs/docs/03-syntax-and-usage/14-using-with-go-templates.md
new file mode 100644
index 000000000..ca74c4200
--- /dev/null
+++ b/docs/docs/03-syntax-and-usage/14-using-with-go-templates.md
@@ -0,0 +1,89 @@
+# Using with `html/template`
+
+Templ components can be used with the Go standard library [`html/template`](https://pkg.go.dev/html/template) package.
+
+## Using `html/template` in a templ component
+
+To use an existing `html/template` in a templ component, use the `templ.FromGoHTML` function.
+
+```templ title="component.templ"
+package testgotemplates
+
+import "html/template"
+
+var goTemplate = template.Must(template.New("example").Parse("
{{ . }}
"))
+
+templ Example() {
+
+
+
+ @templ.FromGoHTML(goTemplate, "Hello, World!")
+
+
+}
+```
+
+```go title="main.go"
+func main() {
+ Example.Render(context.Background(), os.Stdout)
+}
+```
+
+```html title="Output"
+
+
+
+ Hello, World!
+
+
+```
+
+## Using a templ component with `html/template`
+
+To use a templ component within a `html/template`, use the `templ.ToGoHTML` function to render the component into a `template.HTML value`.
+
+```templ title="component.html"
+package testgotemplates
+
+import "html/template"
+
+var example = template.Must(template.New("example").Parse(`
+
+
+ {{ . }}
+
+
+`))
+
+templ greeting() {
+ Hello, World!
+}
+```
+
+```go title="main.go"
+func main() {
+ // Create the templ component.
+ templComponent := greeting()
+
+ // Render the templ component to a `template.HTML` value.
+ html, err := templ.ToGoHTML(context.Background(), templComponent)
+ if err != nil {
+ t.Fatalf("failed to convert to html: %v", err)
+ }
+
+ // Use the `template.HTML` value within the text/html template.
+ err = example.Execute(os.Stdout, html)
+ if err != nil {
+ t.Fatalf("failed to execute template: %v", err)
+ }
+}
+```
+
+```html title="Output"
+
+
+
+ Hello, World!
+
+
+```
diff --git a/docs/docs/03-syntax-and-usage/15-rendering-raw-html.md b/docs/docs/03-syntax-and-usage/15-rendering-raw-html.md
new file mode 100644
index 000000000..2114dd777
--- /dev/null
+++ b/docs/docs/03-syntax-and-usage/15-rendering-raw-html.md
@@ -0,0 +1,31 @@
+# Rendering raw HTML
+
+To render HTML that has come from a trusted source, bypassing all HTML escaping and security mechanisms that templ includes, use the `templ.Raw` function.
+
+:::info
+Only include HTML that comes from a trusted source.
+:::
+
+:::warning
+Use of this function may introduce security vulnerabilities to your program.
+:::
+
+```templ title="component.templ"
+templ Example() {
+
+
+
+ @templ.Raw("Hello, World!
")
+
+
+}
+```
+
+```html title="Output"
+
+
+
+ Hello, World!
+
+
+```
diff --git a/docs/docs/12-integrations/index.md b/docs/docs/12-integrations/index.md
index 3d90b261b..db2ab3155 100644
--- a/docs/docs/12-integrations/index.md
+++ b/docs/docs/12-integrations/index.md
@@ -15,3 +15,7 @@ https://github.com/a-h/templ/tree/main/examples/integration-gin
An example of using templ with go-chi v5 can be found here:
https://github.com/a-h/templ/tree/main/examples/integration-chi
+
+## `template/html`
+
+See [Using with Go templates](../syntax-and-usage/using-with-go-templates)
diff --git a/generator/htmldiff/diff.go b/generator/htmldiff/diff.go
index ab7c8b5b0..e0a33bf41 100644
--- a/generator/htmldiff/diff.go
+++ b/generator/htmldiff/diff.go
@@ -13,6 +13,41 @@ import (
"github.com/google/go-cmp/cmp"
)
+func DiffStrings(expected, actual string) (diff string, err error) {
+ // Format both strings.
+ var wg sync.WaitGroup
+ wg.Add(2)
+
+ var errs []error
+
+ // Format expected.
+ go func() {
+ defer wg.Done()
+ e := new(strings.Builder)
+ err := htmlformat.Fragment(e, strings.NewReader(expected))
+ if err != nil {
+ errs = append(errs, fmt.Errorf("expected html formatting error: %w", err))
+ }
+ expected = e.String()
+ }()
+
+ // Format actual.
+ go func() {
+ defer wg.Done()
+ a := new(strings.Builder)
+ err := htmlformat.Fragment(a, strings.NewReader(actual))
+ if err != nil {
+ errs = append(errs, fmt.Errorf("actual html formatting error: %w", err))
+ }
+ actual = a.String()
+ }()
+
+ // Wait for processing.
+ wg.Wait()
+
+ return cmp.Diff(expected, actual), errors.Join(errs...)
+}
+
func Diff(input templ.Component, expected string) (diff string, err error) {
return DiffCtx(context.Background(), input, expected)
}
diff --git a/generator/test-go-template-in-templ/expected.html b/generator/test-go-template-in-templ/expected.html
new file mode 100644
index 000000000..cf995128f
--- /dev/null
+++ b/generator/test-go-template-in-templ/expected.html
@@ -0,0 +1,6 @@
+
+
+
+ Hello, World!
+
+
diff --git a/generator/test-go-template-in-templ/render_test.go b/generator/test-go-template-in-templ/render_test.go
new file mode 100644
index 000000000..36614f974
--- /dev/null
+++ b/generator/test-go-template-in-templ/render_test.go
@@ -0,0 +1,22 @@
+package testgotemplates
+
+import (
+ _ "embed"
+ "testing"
+
+ "github.com/a-h/templ/generator/htmldiff"
+)
+
+//go:embed expected.html
+var expected string
+
+func TestExample(t *testing.T) {
+ component := Example()
+ diff, err := htmldiff.Diff(component, expected)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if diff != "" {
+ t.Error(diff)
+ }
+}
diff --git a/generator/test-go-template-in-templ/template.templ b/generator/test-go-template-in-templ/template.templ
new file mode 100644
index 000000000..99614ef0f
--- /dev/null
+++ b/generator/test-go-template-in-templ/template.templ
@@ -0,0 +1,14 @@
+package testgotemplates
+
+import "html/template"
+
+var goTemplate = template.Must(template.New("example").Parse("{{ . }}
"))
+
+templ Example() {
+
+
+
+ @templ.FromGoHTML(goTemplate, "Hello, World!")
+
+
+}
diff --git a/generator/test-go-template-in-templ/template_templ.go b/generator/test-go-template-in-templ/template_templ.go
new file mode 100644
index 000000000..98eb42a9f
--- /dev/null
+++ b/generator/test-go-template-in-templ/template_templ.go
@@ -0,0 +1,46 @@
+// Code generated by templ - DO NOT EDIT.
+
+package testgotemplates
+
+//lint:file-ignore SA4006 This context is only used if a nested component is present.
+
+import "github.com/a-h/templ"
+import "context"
+import "io"
+import "bytes"
+
+import "html/template"
+
+var goTemplate = template.Must(template.New("example").Parse("{{ . }}
"))
+
+func Example() templ.Component {
+ return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
+ if !templ_7745c5c3_IsBuffer {
+ templ_7745c5c3_Buffer = templ.GetBuffer()
+ defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var1 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var1 == nil {
+ templ_7745c5c3_Var1 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templ.FromGoHTML(goTemplate, "Hello, World!").Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ if !templ_7745c5c3_IsBuffer {
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
+ }
+ return templ_7745c5c3_Err
+ })
+}
diff --git a/generator/test-raw-elements/expected.html b/generator/test-raw-elements/expected.html
index 8e4ad92a3..86b5e3a6b 100644
--- a/generator/test-raw-elements/expected.html
+++ b/generator/test-raw-elements/expected.html
@@ -14,5 +14,6 @@
}
Hello
+ World