diff --git a/Tests/LibWeb/Text/expected/HTML/set-outerHTML.txt b/Tests/LibWeb/Text/expected/HTML/set-outerHTML.txt
new file mode 100644
index 00000000000..180ebb256ba
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/HTML/set-outerHTML.txt
@@ -0,0 +1,4 @@
+Changed box.
+oldBox='
A box.
'
+newBox='Changed box.
'
+NoModificationAllowedError: Cannot set outer HTML on document
diff --git a/Tests/LibWeb/Text/input/HTML/set-outerHTML.html b/Tests/LibWeb/Text/input/HTML/set-outerHTML.html
new file mode 100644
index 00000000000..3a6185ecbb7
--- /dev/null
+++ b/Tests/LibWeb/Text/input/HTML/set-outerHTML.html
@@ -0,0 +1,20 @@
+
+
+
diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp
index 4c76d1dca5a..8e5455b1bf4 100644
--- a/Userland/Libraries/LibWeb/DOM/Element.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Element.cpp
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1425,9 +1426,29 @@ WebIDL::ExceptionOr Element::outer_html() const
}
// https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-element-outerhtml
-WebIDL::ExceptionOr Element::set_outer_html(String const&)
+WebIDL::ExceptionOr Element::set_outer_html(String const& value)
{
- dbgln("FIXME: Implement Element::set_outer_html()");
+ // 1. Let parent be this's parent.
+ auto* parent = this->parent();
+
+ // 2. If parent is null, return. There would be no way to obtain a reference to the nodes created even if the remaining steps were run.
+ if (!parent)
+ return {};
+
+ // 3. If parent is a Document, throw a "NoModificationAllowedError" DOMException.
+ if (parent->is_document())
+ return WebIDL::NoModificationAllowedError::create(realm(), "Cannot set outer HTML on document"_fly_string);
+
+ // 4. If parent is a DocumentFragment, set parent to the result of creating an element given this's node document, body, and the HTML namespace.
+ if (parent->is_document_fragment())
+ parent = TRY(create_element(document(), HTML::TagNames::body, Namespace::HTML));
+
+ // 5. Let fragment be the result of invoking the fragment parsing algorithm steps given parent and the given value.
+ auto fragment = TRY(DOMParsing::parse_fragment(value, verify_cast(*parent)));
+
+ // 6. Replace this with fragment within this's parent.
+ TRY(parent->replace_child(fragment, *this));
+
return {};
}