{"id":13466707,"url":"https://github.com/excubo-ag/Blazor.LazyStyleSheet","last_synced_at":"2025-03-26T00:31:24.642Z","repository":{"id":53210485,"uuid":"246599954","full_name":"excubo-ag/Blazor.LazyStyleSheet","owner":"excubo-ag","description":null,"archived":false,"fork":false,"pushed_at":"2023-09-30T13:07:31.000Z","size":378,"stargazers_count":12,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-07T20:48:30.149Z","etag":null,"topics":["blazor","css"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/excubo-ag.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-03-11T14:54:25.000Z","updated_at":"2024-07-06T14:41:28.000Z","dependencies_parsed_at":"2024-04-10T05:48:46.316Z","dependency_job_id":null,"html_url":"https://github.com/excubo-ag/Blazor.LazyStyleSheet","commit_stats":{"total_commits":150,"total_committers":5,"mean_commits":30.0,"dds":0.5866666666666667,"last_synced_commit":"2270a94cd5ad302190033f7503a3c5e4a5a7acdf"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excubo-ag%2FBlazor.LazyStyleSheet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excubo-ag%2FBlazor.LazyStyleSheet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excubo-ag%2FBlazor.LazyStyleSheet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excubo-ag%2FBlazor.LazyStyleSheet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/excubo-ag","download_url":"https://codeload.github.com/excubo-ag/Blazor.LazyStyleSheet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245566098,"owners_count":20636390,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blazor","css"],"created_at":"2024-07-31T15:00:49.059Z","updated_at":"2025-03-26T00:31:23.975Z","avatar_url":"https://github.com/excubo-ag.png","language":"C#","funding_links":[],"categories":["Libraries \u0026 Extensions"],"sub_categories":["Tools \u0026 Utilities"],"readme":":warning: With .NET 5 \u0026 .NET 6, it is recommended to use the [scoped CSS](https://docs.microsoft.com/en-us/aspnet/core/blazor/components/css-isolation?view=aspnetcore-5.0) feature instead of this library.\r\n\r\n## Excubo.Blazor.LazyStyleSheet\r\n\r\n[![Nuget](https://img.shields.io/nuget/v/Excubo.Blazor.LazyStyleSheet)](https://www.nuget.org/packages/Excubo.Blazor.LazyStyleSheet/)\r\n[![Nuget](https://img.shields.io/nuget/dt/Excubo.Blazor.LazyStyleSheet)](https://www.nuget.org/packages/Excubo.Blazor.LazyStyleSheet/)\r\n[![GitHub](https://img.shields.io/github/license/excubo-ag/Blazor.LazyStyleSheet)](https://github.com/excubo-ag/Blazor.LazyStyleSheet)\r\n\r\nA major issue on websites is slow page load. In part, this is due to enormous payloads that need to be downloaded in full before a page can be rendered correctly. Minimization and compression help to some degree, but it ignores the awkward fact that many style sheets are only used to a tiny fraction.\r\n\r\nWith HTTP/2, loading small files rather than one large one is less of a performance concern than with HTTP/1.1. Since Blazor uses HTTP/2 by default, we can make use of this and split style sheets into smaller chunks. Those chunks can then be loaded lazily, i.e. only when a component actually needs it.\r\n\r\nExcubo.Blazor.LazyStyleSheet enables you to write dedicated style sheet for each component.\r\n\r\n## Breaking changes\r\n\r\n### Version 3.X.Y\r\n\r\nGood news! Adding lazy-loaded style sheets to your component just became a whole lot easier. Simply add `\u003cStylesheet Src=\"path/to/my/style.css\" /\u003e` to any component.\r\nIf you write your styles as a `Component.razor.css` file, you don't need to do anything.\r\nAnd you can now also remove the `\u003cStyleSheets /\u003e` component in your `App.razor`, as well as the dependency injection code in your `Startup.cs`.\r\n\r\n### Version 2.X.Y\r\n\r\n`Excubo.Blazor.LazyStyleSheet` now contains build tasks to automatically inject the `IStyleSheetService` when you write your component style as a `Component.razor.css` or `Component.razor.scss` file. That means, if you previously manually inserted `IStyleSheetService` into your component, you now have to remove that.\r\n\r\n## How to use\r\n\r\n### 1. Install the nuget package Excubo.Blazor.LazyStyleSheet\r\n\r\nExcubo.Blazor.LazyStyleSheet is distributed [via nuget.org](https://www.nuget.org/packages/Excubo.Blazor.LazyStyleSheet/).\r\n[![Nuget](https://img.shields.io/nuget/v/Excubo.Blazor.LazyStyleSheet)]((https://www.nuget.org/packages/Excubo.Blazor.LazyStyleSheet/))\r\n\r\n#### Package Manager:\r\n```ps\r\nInstall-Package Excubo.Blazor.LazyStyleSheet\r\n```\r\n\r\n#### .NET Cli:\r\n```cmd\r\ndotnet add package Excubo.Blazor.LazyStyleSheet\r\n```\r\n\r\n#### Package Reference\r\n```xml\r\n\u003cPackageReference Include=\"Excubo.Blazor.LazyStyleSheet\" /\u003e\r\n```\r\n\r\n### 2a. Write your style sheets and put them next to your component\r\n\r\n`MyComponent.razor`:\r\n```razor\r\n@page \"/hello\"\r\n\r\n\u003cdiv class=\"mystyle\"\u003eMy styled component\u003c/div\u003e\r\n\r\n```\r\n\r\n`MyComponent.razor.css` / `MyComponent.razor.scss`: \r\n```css\r\n.mystyle {\r\n    color: purple\r\n}\r\n```\r\n\r\n### 2b. Load any stylesheet in your component\r\n\r\n`MyComponent.razor`:\r\n```razor\r\n@page \"/hello\"\r\n\r\n\u003cStylesheet Src=\"path/to/my/style.min.css\" /\u003e\r\n\u003cdiv class=\"mystyle\"\u003eMy styled component\u003c/div\u003e\r\n\r\n```\r\n\r\n## Remark\r\n\r\n - Style sheet urls may be added any number of times, and will only be added to the DOM once (as duplicate `\u003clink\u003e` tags don't achieve anything). This only applies if the url string matches exactly, i.e. there is a difference between `https://localhost/css/style.css` and `css/style.css`.\r\n\r\n\r\n## Tips \u0026 tricks\r\n\r\n### Integration with webcompiler\r\n\r\n`Excubo.Blazor.LazyStyleSheet` integrates seemlessly with [`Excubo.WebCompiler`](https://github.com/excubo-ag/WebCompiler). If you have webcompiler installed, a build task will take care of scss/sass compilation, minification, and compression. The use of webcompiler is strictly optional, but recommended and active by default.\r\n\r\n### Configuration options\r\n\r\nThis library can be configured by adding values to your `csproj` file:\r\n\r\n```xml\r\n  \u003cPropertyGroup\u003e\r\n    \u003cLazyStyleSheets_StaticAssetFolder\u003ewwwroot\u003c/LazyStyleSheets_StaticAssetFolder\u003e\r\n    \u003cLazyStyleSheets_ComponentStyleFolder\u003ecss/components\u003c/LazyStyleSheets_ComponentStyleFolder\u003e\r\n    \u003cLazyStyleSheets_UseMinifiedStyleSheets\u003etrue\u003c/LazyStyleSheets_UseMinifiedStyleSheets\u003e\r\n    \u003cLazyStyleSheets_UseGzippedStyleSheets\u003efalse\u003c/LazyStyleSheets_UseGzippedStyleSheets\u003e\r\n    \u003cLazyStyleSheets_UseWebCompiler\u003etrue\u003c/LazyStyleSheets_UseWebCompiler\u003e\r\n    \u003cLazyStyleSheets_AutoInject\u003etrue\u003c/LazyStyleSheets_AutoInject\u003e\r\n  \u003c/PropertyGroup\u003e\r\n```\r\n\r\n#### StaticAssetFolder\r\n\r\nThe static asset folder should be set to the name of the folder where all your static assets are. By default, that's `wwwroot` and does not need to be changed.\r\n\r\n#### ComponentStyleFolder\r\n\r\n`Excubo.Blazor.LazyStyleSheet` puts all `*.razor.css` and `*.razor.scss` files into a subfolder of the static asset folder, to separate them from other styles. The default location is `css/components`, so the full path becomes `wwwroot/css/components` by default.\r\n\r\n#### UseMinifiedStyleSheets\r\n\r\n`Excubo.Blazor.LazyStyleSheet` uses [`Excubo.WebCompiler`](https://github.com/excubo-ag/WebCompiler), if installed. It then generates minified, and compressed versions of your style sheet automatically. By default, `Excubo.Blazor.LazyStyleSheet` then uses the minified version to dynamically and lazily load the style sheet.\r\nIf you do not have `Excubo.WebCompiler` installed, and you do not generate minified versions of your style sheets any other way, you need to set UseMinifiedStyleSheets to `false`\r\n\r\n```xml\r\n  \u003cPropertyGroup\u003e\r\n    \u003c!-- set these values, if you do not use Excubo.WebCompiler or any other minification and compression pipeline --\u003e\r\n    \u003cLazyStyleSheets_UseMinifiedStyleSheets\u003efalse\u003c/LazyStyleSheets_UseMinifiedStyleSheets\u003e\r\n    \u003cLazyStyleSheets_UseGzippedStyleSheets\u003efalse\u003c/LazyStyleSheets_UseGzippedStyleSheets\u003e\r\n    \u003cLazyStyleSheets_UseWebCompiler\u003efalse\u003c/LazyStyleSheets_UseWebCompiler\u003e\r\n  \u003c/PropertyGroup\u003e\r\n```\r\n\r\n#### UseGzippedStyleSheets\r\n\r\nSame as with `UseMinifiedStyleSheets`, serving compressed version of your style sheets is also supported, but deactivated by default. This is because Kestrel does not handle gzipped style sheets correctly by default.\r\n\r\nTo enable this, add the following to your `Startup.cs` file:\r\n\r\n```cs\r\npublic void Configure(IApplicationBuilder app, IWebHostEnvironment env)\r\n{\r\n    /// ...\r\n    /// ...\r\n    \r\n    app.UseStaticFiles(new StaticFileOptions\r\n    {\r\n        OnPrepareResponse = context =\u003e\r\n        {\r\n            var headers = context.Context.Response.Headers;\r\n            HandleCompressedResourced(context, headers);\r\n        }\r\n    });\r\n    app.UseStaticFiles();\r\n\r\n    /// ...\r\n    /// ...\r\n}\r\n\r\nprivate static void HandleCompressedResourced(StaticFileResponseContext context, IHeaderDictionary headers)\r\n{\r\n    if (context.File == null)\r\n    {\r\n        return;\r\n    }\r\n    if ((string)headers[\"Content-Type\"] != \"application/x-gzip\")\r\n    {\r\n        return;\r\n    }\r\n    headers.Add(\"Content-Encoding\", \"gzip\");\r\n    if (context.File.Name.EndsWith(\"js.gz\", System.StringComparison.InvariantCultureIgnoreCase))\r\n    {\r\n        headers[\"Content-Type\"] = \"application/javascript\";\r\n    }\r\n    if (context.File.Name.EndsWith(\"css.gz\", System.StringComparison.InvariantCultureIgnoreCase))\r\n    {\r\n        headers[\"Content-Type\"] = \"text/css\";\r\n    }\r\n}\r\n```\r\n\r\nActivate use of compressed resources in your `csproj` file:\r\n\r\n```xml\r\n  \u003cPropertyGroup\u003e\r\n    \u003cLazyStyleSheets_UseGzippedStyleSheets\u003etrue\u003c/LazyStyleSheets_UseGzippedStyleSheets\u003e\r\n  \u003c/PropertyGroup\u003e\r\n```\r\n\r\n#### Auto Inject\r\n\r\nA convenient way of writing styled components is to put the scss/css file in the same folder as the component and name the style file according to the component, e.g. `Component.razor` and `Component.razor.css`.\r\nThat way the css file gets grouped with the component in Visual Studio (and other IDEs with file nesting capability).\r\n\r\nThis library goes one step further, by making sure that components developed this way automatically have the style injected. If you want to opt out of this feature, simply set `\u003cLazyStyleSheets_AutoInject\u003efalse\u003c/LazyStyleSheets_AutoInject\u003e`.\r\n\r\n:warning: If you use a custom namespace for your component (i.e. you have an `@namespace SomeNamespace` directive in your component), then AutoInject won't work for you. Use a `\u003cStylesheet Src=\"...\" /\u003e` instead.\r\n\r\n## Contribute\r\n\r\nIf you encounter any issues or have ideas for new features, please raise an issue in this repository.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexcubo-ag%2FBlazor.LazyStyleSheet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexcubo-ag%2FBlazor.LazyStyleSheet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexcubo-ag%2FBlazor.LazyStyleSheet/lists"}