diff --git a/aspnetcore/blazor/components/class-libraries.md b/aspnetcore/blazor/components/class-libraries.md
index 904b3d9a5d90..b3fb75d8285e 100644
--- a/aspnetcore/blazor/components/class-libraries.md
+++ b/aspnetcore/blazor/components/class-libraries.md
@@ -252,7 +252,7 @@ The distinction between using the `Link` component in a child component and plac
* Can be modified by application state. A hard-coded `` HTML tag can't be modified by application state.
* Is removed from the HTML `
` when the parent component is no longer rendered.
-## Create an RCL with static assets
+## Create an RCL with static assets in the `wwwroot` folder
An RCL's static assets are available to any app that consumes the library.
@@ -311,6 +311,10 @@ Rendered `Jeep` component:
For more information, see .
+## Create an RCL with JavaScript files collocated with components
+
+[!INCLUDE[](~/includes/js-collocation.md)]
+
## Supply components and static assets to multiple hosted Blazor apps
For more information, see .
diff --git a/aspnetcore/blazor/javascript-interoperability/index.md b/aspnetcore/blazor/javascript-interoperability/index.md
index b910958c7f64..2a3141022423 100644
--- a/aspnetcore/blazor/javascript-interoperability/index.md
+++ b/aspnetcore/blazor/javascript-interoperability/index.md
@@ -40,7 +40,8 @@ Load JavaScript (JS) code using any of the following approaches:
* [Load a script in `` markup](#load-a-script-in-head-markup) (*Not generally recommended*)
* [Load a script in `` markup](#load-a-script-in-body-markup)
-* [Load a script from an external JS file (`.js`)](#load-a-script-from-an-external-js-file-js)
+* [Load a script from an external JavaScript file (`.js`) collocated with a component](#load-a-script-from-an-external-javascript-file-js-collocated-with-a-component)
+* [Load a script from an external JavaScript file (`.js`)](#load-a-script-from-an-external-javascript-file-js)
* [Inject a script after Blazor starts](#inject-a-script-after-blazor-starts)
> [!WARNING]
@@ -53,7 +54,7 @@ Load JavaScript (JS) code using any of the following approaches:
*The approach in this section isn't generally recommended.*
-Place the script (``) in the `` element markup of `wwwroot/index.html` (Blazor WebAssembly) or `Pages/_Layout.cshtml` (Blazor Server):
+Place the JavaScript (JS) tags (``) in the `` element markup of `wwwroot/index.html` (Blazor WebAssembly) or `Pages/_Layout.cshtml` (Blazor Server):
```html
@@ -74,7 +75,7 @@ Loading JS from the `` isn't the best approach for the following reasons:
### Load a script in `` markup
-Place the script (``) inside the closing `` element markup of `wwwroot/index.html` (Blazor WebAssembly) or `Pages/_Layout.cshtml` (Blazor Server):
+Place the JavaScript (JS) tags (``) inside the closing `` element markup of `wwwroot/index.html` (Blazor WebAssembly) or `Pages/_Layout.cshtml` (Blazor Server):
```html
@@ -91,9 +92,15 @@ Place the script (``) inside the closing `` element
The `{webassembly|server}` placeholder in the preceding markup is either `webassembly` for a Blazor WebAssembly app (`blazor.webassembly.js`) or `server` for a Blazor Server app (`blazor.server.js`).
-### Load a script from an external JS file (`.js`)
+### Load a script from an external JavaScript file (`.js`) collocated with a component
-Place the script (``) with a script `src` path inside the closing `` tag after the Blazor script reference.
+[!INCLUDE[](~/includes/js-collocation.md)]
+
+For more information on RCLs, see .
+
+### Load a script from an external JavaScript file (`.js`)
+
+Place the JavaScript (JS) tags (``) with a script source (`src`) path inside the closing `` tag after the Blazor script reference.
In `wwwroot/index.html` (Blazor WebAssembly) or `Pages/_Layout.cshtml` (Blazor Server):
diff --git a/aspnetcore/includes/js-collocation.md b/aspnetcore/includes/js-collocation.md
new file mode 100644
index 000000000000..5d822007894a
--- /dev/null
+++ b/aspnetcore/includes/js-collocation.md
@@ -0,0 +1,49 @@
+---
+no-loc: [Home, Privacy, Kestrel, appsettings.json, "ASP.NET Core Identity", cookie, Cookie, Blazor, "Blazor Server", "Blazor WebAssembly", "Identity", "Let's Encrypt", Razor, SignalR]
+---
+Collocation of JavaScript (JS) files for pages, views, and Razor components is a convenient way to organize scripts in an app.
+
+Collocate JS files using the following filename extension conventions:
+
+* Pages of Razor Pages apps and views of MVC apps: `.cshtml.js`. Examples:
+ * `Pages/Contact.cshtml.js` for the `Contact` page of a Razor Pages app at `Pages/Contact.cshtml`.
+ * `Views/Home/Contact.cshtml.js` for the `Contact` view of an MVC app at `Views/Home/Contact.cshtml`.
+* Razor components of Blazor apps: `.razor.js`. Example: `Pages/Index.razor.js` for the `Index` component at `Pages/Index.razor`.
+
+Collocated JS files are publicly addressable using the path to the file in the project:
+
+* Pages, views, and components from a collocated scripts file in the app:
+
+ `{PATH}/{PAGE, VIEW, OR COMPONENT}.{EXTENSION}`
+
+ * The `{PATH}` placeholder is the path to the page, view, or component.
+ * The `{PAGE, VIEW, OR COMPONENT}` placeholder is the page, view, or component.
+ * The `{EXTENSION}` placeholder matches the extension of the page, view, or component, either `razor` or `cshtml`, followed by `.js`.
+
+ In the following example from a Razor Pages app, the script is collocated in the `Pages` folder with the `Contact` page (`Pages/Contact.cshtml`):
+
+ ```razor
+ @section Scripts {
+
+ }
+ ```
+
+* For scripts provided by a Razor class library (RCL):
+
+ `_content/{PACKAGE ID}/{PATH}/{PAGE, VIEW, OR COMPONENT}.{EXTENSION}`
+
+ * The `{PACKAGE ID}` placeholder is the RCL's package identifier (or library name for a class library referenced by the app).
+ * The `{PATH}` placeholder is the path to the page, view, or component. If a Razor component is located at the root of the RCL, the path segment isn't included.
+ * The `{PAGE, VIEW, OR COMPONENT}` placeholder is the page, view, or component.
+ * The `{EXTENSION}` placeholder matches the extension of page, view, or component, either `razor` or `cshtml`, followed by `.js`.
+
+ In the following Blazor app example:
+
+ * The RCL's package identifier is `AppJS`.
+ * A module's scripts are loaded for the `Index` component (`Index.razor`).
+ * The `Index` component is in the `Pages` folder of the RCL.
+
+ ```csharp
+ var module = await JS.InvokeAsync("import",
+ "_content/AppJS/Pages/Index.razor.js");
+ ```