diff --git a/modules/ROOT/images/graph_match_clause.svg b/modules/ROOT/images/graph_match_clause.svg
index d2481798f..393b3fe23 100644
--- a/modules/ROOT/images/graph_match_clause.svg
+++ b/modules/ROOT/images/graph_match_clause.svg
@@ -1 +1 @@
-
+
\ No newline at end of file
diff --git a/modules/ROOT/pages/appendix/gql-conformance/additional-cypher.adoc b/modules/ROOT/pages/appendix/gql-conformance/additional-cypher.adoc
index 46134dceb..837a32330 100644
--- a/modules/ROOT/pages/appendix/gql-conformance/additional-cypher.adoc
+++ b/modules/ROOT/pages/appendix/gql-conformance/additional-cypher.adoc
@@ -78,6 +78,93 @@ Either the pattern already exists, or it needs to be created.
| Syntactic construct for creating a `LIST` based on matchings of a pattern.
|===
+[[dynamic-queries]]
+== Dynamic queries
+
+Node labels, relationship types, properties, and CSV columns can be referenced dynamically using Cypher.
+This allows for more flexible queries and mitigates the risk of Cypher injection.
+(For more information about Cypher injection, see link:https://neo4j.com/developer/kb/protecting-against-cypher-injection/[Neo4j Knowledge Base -> Protecting against Cypher injection]).
+
+[options="header", cols="2a,5a"]
+|===
+| Cypher feature
+| Description
+
+a|
+[source, cypher, role="noheader"]
+----
+MATCH (n:$($label)),
+ ()-[r:$($type))]->()
+----
+
+| xref:clauses/match.adoc#dynamic-match[`MATCH` nodes and relationships using dynamic node labels and relationship types]
+
+a|
+[source, cypher, role="noheader"]
+----
+CREATE (n:$($label)),
+ ()-[r:$($type)]->()
+----
+
+| xref:clauses/create.adoc#dynamic-create[`CREATE` nodes and relationships using dynamic node labels and relationship types]
+
+a|
+[source, cypher, role="noheader"]
+----
+MERGE (n:$($label)),
+ ()-[r:$($type)]->()
+----
+
+| xref:clauses/merge.adoc#dynamic-merge[`MERGE` nodes and relationships using dynamic node labels and relationship types]
+
+a|
+[source, cypher, role="noheader"]
+----
+LOAD CSV WITH HEADERS FROM 'file:///artists-with-headers.csv' AS line
+CREATE (n:$(line.label) {name: line.Name})
+----
+
+| xref:clauses/load-csv.adoc#dynamic-columns[Import CSV files using dynamic columns]
+
+
+a|
+[source, cypher, role="noheader"]
+----
+MATCH (n)
+SET n[$key] = value
+----
+
+| xref:clauses/set.adoc#dynamic-set-property[Dynamically `SET` or update a property]
+
+a|
+[source, cypher, role="noheader"]
+----
+MATCH (n:Label)
+SET n:$(n.property)
+----
+
+| xref:clauses/set.adoc#dynamic-set-node-label[Dynamically `SET` a node label]
+
+a|
+[source, cypher, role="noheader"]
+----
+MATCH (n {name: 'Peter'})
+REMOVE n:$($label)
+----
+
+| xref:clauses/remove.adoc#dynamic-remove-property[Dynamically `REMOVE` a property]
+
+a|
+[source, cypher, role="noheader"]
+----
+MATCH (n {name: 'Peter'})
+REMOVE n:$($label)
+----
+
+| xref:clauses/remove.adoc#dynamic-remove-node-label[Dynamically `REMOVE` a node label]
+
+|===
+
[[functions]]
== Functions
diff --git a/modules/ROOT/pages/clauses/create.adoc b/modules/ROOT/pages/clauses/create.adoc
index 9749ac375..f2ee2cd58 100644
--- a/modules/ROOT/pages/clauses/create.adoc
+++ b/modules/ROOT/pages/clauses/create.adoc
@@ -205,10 +205,61 @@ Nodes created: 2 +
Properties set: 4
|===
+[role=label--new-5.26]
+[[dynamic-create]]
+== CREATE using dynamic node labels and relationship types
+
+Node labels and relationship types can be referenced dynamically in expressions, parameters, and variables when creating nodes and relationships.
+This allows for more flexible queries and mitigates the risk of Cypher injection.
+(For more information about Cypher injection, see link:https://neo4j.com/developer/kb/protecting-against-cypher-injection/[Neo4j Knowledge Base -> Protecting against Cypher injection]).
+
+.Syntax for creating nodes and relationships dynamically
+[source, syntax]
+----
+CREATE (n:$())
+CREATE ()-[r:$()]->()
+----
+
+The expression must evaluate to a `STRING NOT NULL | LIST NOT NULL` value.
+Using a `LIST` with more than one item when creating a relationship using dynamic relationship types will fail.
+This is because a relationship can only have exactly one type.
+
+.Parameters
+[source, parameters]
+----
+{
+ "nodeLabels": ["Person", "Director"],
+ "relType": "DIRECTED",
+ "movies": ["Ladybird", "Little Women", "Barbie"]
+}
+----
+
+.Create nodes and relationships using dynamic node labels and relationship types
+[source, cypher]
+----
+CREATE (greta:$($nodeLabels) {name: 'Greta Gerwig'})
+WITH greta
+UNWIND $movies AS movieTitle
+CREATE (greta)-[rel:$($relType)]->(m:Movie {title: movieTitle})
+RETURN greta.name AS name, labels(greta) AS labels, type(rel) AS relType, collect(m.title) AS movies
+----
+
+.Result
+[role="queryresult",options="footer",cols="4* Protecting against Cypher injection]).
+
+.bands-with-headers.csv
+[source, csv, filename="artists-with-headers.csv"]
+----
+Id,Label,Name
+1,Band,The Beatles
+2,Band,The Rolling Stones
+3,Band,Pink Floyd
+4,Band,Led Zeppelin
+----
+
+.Query
+[source, cypher, role=test-skip]
+----
+LOAD CSV WITH HEADERS FROM 'file:///bands-with-headers.csv' AS line
+MERGE (n:$(line.Label) {name: line.Name})
+RETURN n AS bandNodes
+----
+
+.Result
+[role="queryresult",options="header,footer",cols="1*(wallStreet),
(martin)-[:ACTED_IN {role: 'Carl Fox'}]->(wallStreet),
@@ -124,8 +124,10 @@ The above query uses the xref:functions/list.adoc#functions-labels[`labels()`] a
[role="queryresult",options="header,footer",cols="2* Label expressions].
@@ -490,3 +492,126 @@ The above query uses the xref:functions/aggregating.adoc#functions-collect[`coll
For more information about how Cypher queries work, see xref:clauses/clause-composition.adoc[].
+[role=label--new-5.26]
+[[dynamic-match]]
+== MATCH using dynamic node labels and relationship types
+
+Node labels and relationship types can be referenced dynamically in expressions, parameters, and variables when matching nodes and relationships.
+This allows for more flexible queries and mitigates the risk of Cypher injection.
+(For more information about Cypher injection, see link:https://neo4j.com/developer/kb/protecting-against-cypher-injection/[Neo4j Knowledge Base -> Protecting against Cypher injection]).
+
+.Syntax for matching node labels dynamically
+[source, syntax]
+----
+MATCH (n:$())
+MATCH (n:$any())
+MATCH (n:$all())
+----
+
+[NOTE]
+`MATCH (n:$all())` is functionally equivalent to `MATCH (n:$())`.
+
+.Syntax for matching relationship types dynamically
+[source, syntax]
+----
+MATCH ()-[r:$())]->()
+MATCH ()-[r:$any()]->()
+MATCH ()-[r:$all())]->()
+----
+
+The expression must evaluate to a `STRING NOT NULL | LIST NOT NULL` value.
+If you use a `LIST` with more than one item in a relationship pattern with dynamic relationship types, no results will be returned.
+This is because a relationship can only have exactly one type.
+
+[NOTE]
+Queries using dynamic values may not be as performant as those using static values.
+This is because the xref:planning-and-tuning/execution-plans.adoc[Cypher planner] uses statically available information when planning queries to determine whether to use an xref:indexes/search-performance-indexes/overview.adoc[index] or not, and this is not possible when using dynamic values.
+
+.Match labels dynamically
+[source, cypher]
+----
+WITH ["Person", "Director"] AS labels
+MATCH (directors:$(labels))
+RETURN directors
+----
+
+.Result
+[role="queryresult",options="header,footer",cols="1*()
+RETURN relationshipType, count(r) AS relationshipCount
+----
+
+.Result
+[role="queryresult",options="header,footer",cols="2* Protecting against Cypher injection]).
+
+.Syntax for merging nodes and relationships dynamically
+[source, syntax]
+----
+MERGE (n:$())
+MERGE ()-[r:$()]->()
+----
+
+The expression must evaluate to a `STRING NOT NULL | LIST NOT NULL` value.
+Using a `LIST` with more than one item when merging a relationship using dynamic relationship types will fail.
+This is because a relationship can only have exactly one type.
+
+[NOTE]
+Queries using dynamic values may not be as performant as those using static values.
+This is because the xref:planning-and-tuning/execution-plans.adoc[Cypher planner] uses statically available information when planning queries to determine whether to use an xref:indexes/search-performance-indexes/overview.adoc[index] or not, and this is not possible when using dynamic values.
+
+.Parameters
+[source, parameters]
+----
+{
+ "nodeLabels": ["Person", "Director"],
+ "relType": "DIRECTED",
+ "movies": ["Ladybird", "Little Women", "Barbie"]
+}
+----
+
+.Merge nodes and relationships using dynamic node labels and relationship types
+[source, cypher]
+----
+MERGE (greta:$($nodeLabels) {name: 'Greta Gerwig'})
+WITH greta
+UNWIND $movies AS movieTitle
+MERGE (greta)-[rel:$($relType)]->(m:Movie {title: movieTitle})
+RETURN greta.name AS name, labels(greta) AS labels, type(rel) AS relType, collect(m.title) AS movies
+----
+
+.Result
+[role="queryresult",options="footer",cols="3* Protecting against Cypher injection]).
[source, syntax]
----
@@ -82,7 +84,6 @@ REMOVE n[key]
The dynamically calculated key must evaluate to a `STRING` value.
This query creates a copy of every property on the nodes:
-
.Query
[source, cypher, indent=0]
----
@@ -131,18 +132,19 @@ Labels removed: 1
|===
[role=label--new-5.24]
-[[remove-remove-a-label-dynamically-from-a-node]]
-== Dynamically removing a label
+[[dynamic-remove-node-label]]
+== Dynamically remove a node label
`REMOVE` can be used to remove a label on a node even when the label is not statically known.
-
[source, syntax]
----
MATCH (n)
REMOVE n:$(expr)
----
+The expression must evaluate to a `STRING NOT NULL | LIST NOT NULL` value.
+
.Query
[source, cypher, indent=0]
----
diff --git a/modules/ROOT/pages/clauses/set.adoc b/modules/ROOT/pages/clauses/set.adoc
index 6976c8abe..d90a891d1 100644
--- a/modules/ROOT/pages/clauses/set.adoc
+++ b/modules/ROOT/pages/clauses/set.adoc
@@ -162,10 +162,12 @@ Properties set: 1
[role=label--new-5.24]
-[[set-dynamically-a-property]]
-== Dynamically setting or updating a property
+[[dynamic-set-property]]
+== Dynamically set or update a property
`SET` can be used to set or update a property on a node or relationship even when the property key name is not statically known.
+This allows for more flexible queries and mitigates the risk of Cypher injection.
+(For more information about Cypher injection, see link:https://neo4j.com/developer/kb/protecting-against-cypher-injection/[Neo4j Knowledge Base -> Protecting against Cypher injection]).
[source, syntax]
----
@@ -541,15 +543,15 @@ Labels added: 1
|===
[role=label--new-5.24]
-[[set-set-a-dynamic-label-on-a-node]]
-== Dynamically setting a label
+[[dynamic-set-node-label]]
+== Dynamically set a node label
`SET` can be used to set a label on a node even when the label is not statically known.
[source, syntax]
----
MATCH (n)
-SET n:$(expr)
+SET n:$()
----
.Query
@@ -629,7 +631,7 @@ Labels added: 2
|===
[role=label--new-5.24]
-[[set-set-multiple-dynamic-labels-on-a-node]]
+[[dynamic-set-multiple-node-labels]]
== Set multiple labels dynamically on a node
It is possible to set multiple labels dynamically using a `LIST` and/or by chaining them separately with a `:`:
diff --git a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc
index 9decf9b67..432f5b253 100644
--- a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc
+++ b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc
@@ -184,6 +184,45 @@ GRANT READ {*} ON GRAPH * FOR (n) WHERE n.createdAt > date('2024-10-25') TO regu
|===
+=== New features
+
+[cols="2", options="header"]
+|===
+| Feature
+| Details
+
+a|
+label:functionality[]
+label:new[]
+[source, cypher, role="noheader"]
+----
+MATCH (n:$($label)),
+ ()-[r:$($type))]->()
+----
+
+[source, cypher, role="noheader"]
+----
+CREATE (n:$($label)),
+ ()-[r:$($type)]->()
+----
+
+[source, cypher, role="noheader"]
+----
+MERGE (n:$($label)),
+ ()-[r:$($type)]->()
+----
+
+[source, cypher, role="noheader"]
+----
+LOAD CSV WITH HEADERS FROM 'file:///artists-with-headers.csv' AS line
+CREATE (n:$(line.label) {name: line.Name})
+----
+
+| Added the ability to dynamically reference node labels and relationship types in xref:clauses/match.adoc#dynamic-match[`MATCH`], xref:clauses/create.adoc#dynamic-create[`CREATE`], and xref:clauses/merge.adoc#dynamic-merge[`MERGE`] clauses.
+Also introduced the ability to specify CSV columns dynamically when using xref:clauses/load-csv.adoc#dynamic-load[`LOAD CSV`].
+|===
+
+
[[cypher-deprecations-additions-removals-5.25]]
== Neo4j 5.25
@@ -319,7 +358,7 @@ label:new[]
SET n[$prop] = "hello world"
REMOVE n[$prop]
----
-| Added the ability to dynamically reference properties in xref:clauses/set.adoc#set-dynamically-a-property[SET] and xref:clauses/remove.adoc#remove-remove-a-property-dynamically[REMOVE] clauses.
+| Added the ability to dynamically reference properties in xref:clauses/set.adoc#dynamic-set-property[SET] and xref:clauses/remove.adoc#dynamic-remove-property[REMOVE] clauses.
a|
label:functionality[]