diff --git a/config/hyde.php b/config/hyde.php
index 08ffd8f946a..fb5c4b547a2 100644
--- a/config/hyde.php
+++ b/config/hyde.php
@@ -187,7 +187,21 @@
| Hyde ships with an app.css file containing compiled TailwindCSS styles
| in the _media/ directory. If you want to load this file from the
| HydeFront JsDelivr CDN, you can set this setting to true.
+ |
*/
'load_app_styles_from_cdn' => false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Tailwind Play CDN
+ |--------------------------------------------------------------------------
+ |
+ | The next setting enables a script for the TailwindCSS Play CDN which will
+ | compile CSS in the browser. While this is useful for local development
+ | it's not recommended for production use. To keep things consistent,
+ | your Tailwind configuration file will be injected into the HTML.
+ */
+
+ 'use_play_cdn' => false,
];
diff --git a/docs/creating-content/managing-assets.md b/docs/creating-content/managing-assets.md
index cb339c366a6..687db384331 100644
--- a/docs/creating-content/managing-assets.md
+++ b/docs/creating-content/managing-assets.md
@@ -89,6 +89,14 @@ For the absolute majority of the cases, you don't need to mess with these files.
#### Loading from CDN
If you want to load the same pre-compiled file included with Hyde but from a CDN, you can set `load_app_styles_from_cdn` to `true` in the `config/hyde.php` file. While you lose the ability to customize it, your styles will be automatically updated when needed.
+### Using the TailwindCSS Play CDN
+
+If you want to use the [TailwindCSS Play CDN](https://tailwindcss.com/docs/installation/play-cdn), you can set `use_play_cdn` to `true` in the `config/hyde.php` file.
+This will in addition to loading the standard app.css file also add a script tag to load the TailwindCSS Play CDN.
+What's even better is that Hyde will also inject the contents of the included `tailwind.config.js` file into the script tag, so the Play CDN styles match the ones created by Laravel Mix.
+This also means you can tinker around with the TailwindCSS settings without having to compile anything.
+
+>warn Note that the Play CDN is not meant for production use, so enabling it will add a warning to the web console.
## Managing images
As mentioned above, assets stored in the _media folder are automatically copied to the _site/media folder,
diff --git a/packages/framework/config/hyde.php b/packages/framework/config/hyde.php
index 08ffd8f946a..fb5c4b547a2 100644
--- a/packages/framework/config/hyde.php
+++ b/packages/framework/config/hyde.php
@@ -187,7 +187,21 @@
| Hyde ships with an app.css file containing compiled TailwindCSS styles
| in the _media/ directory. If you want to load this file from the
| HydeFront JsDelivr CDN, you can set this setting to true.
+ |
*/
'load_app_styles_from_cdn' => false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Tailwind Play CDN
+ |--------------------------------------------------------------------------
+ |
+ | The next setting enables a script for the TailwindCSS Play CDN which will
+ | compile CSS in the browser. While this is useful for local development
+ | it's not recommended for production use. To keep things consistent,
+ | your Tailwind configuration file will be injected into the HTML.
+ */
+
+ 'use_play_cdn' => false,
];
diff --git a/packages/framework/resources/views/layouts/styles.blade.php b/packages/framework/resources/views/layouts/styles.blade.php
index 379c18af910..00a3135a895 100644
--- a/packages/framework/resources/views/layouts/styles.blade.php
+++ b/packages/framework/resources/views/layouts/styles.blade.php
@@ -8,5 +8,12 @@
@endif
+{{-- Dynamic TailwindCSS Play CDN --}}
+@if(config('hyde.use_play_cdn', false))
+
+
+
+@endif
+
{{-- Add any extra styles to include after the others --}}
-@stack('styles')
\ No newline at end of file
+@stack('styles')
diff --git a/packages/framework/src/Facades/Asset.php b/packages/framework/src/Facades/Asset.php
index 5a2e5b3028f..ab658c4a1a2 100644
--- a/packages/framework/src/Facades/Asset.php
+++ b/packages/framework/src/Facades/Asset.php
@@ -18,6 +18,7 @@
* @method static string cdnLink(string $file)
* @method static string mediaLink(string $file)
* @method static bool hasMediaFile(string $file)
+ * @method static string injectTailwindConfig()
*/
class Asset extends Facade
{
diff --git a/packages/framework/src/Framework/Services/AssetService.php b/packages/framework/src/Framework/Services/AssetService.php
index b8e5ee4f92a..6a00d84b9a4 100644
--- a/packages/framework/src/Framework/Services/AssetService.php
+++ b/packages/framework/src/Framework/Services/AssetService.php
@@ -5,6 +5,8 @@
namespace Hyde\Framework\Services;
use Hyde\Hyde;
+use Illuminate\Support\Str;
+use function str_contains;
/**
* Handles the retrieval of core asset files. Commonly used through the Asset facade.
@@ -50,6 +52,19 @@ public function hasMediaFile(string $file): bool
return file_exists(Hyde::path('_media').'/'.$file);
}
+ public function injectTailwindConfig(): string
+ {
+ $config = Str::between(file_get_contents(Hyde::path('tailwind.config.js')), '{', '}');
+
+ if (str_contains($config, 'plugins: [')) {
+ $tokens = explode('plugins: [', $config, 2);
+ $tokens[1] = Str::after($tokens[1], ']');
+ $config = implode('', $tokens);
+ }
+
+ return preg_replace('/\s+/', ' ', "/* tailwind.config.js */ \n".rtrim($config, ",\n\r"));
+ }
+
protected function getCacheBustKey(string $file): string
{
if (! config('hyde.cache_busting', true)) {
diff --git a/packages/framework/tests/Feature/AssetServiceTest.php b/packages/framework/tests/Feature/AssetServiceTest.php
index 0250046c1ba..913facd0e6e 100644
--- a/packages/framework/tests/Feature/AssetServiceTest.php
+++ b/packages/framework/tests/Feature/AssetServiceTest.php
@@ -53,4 +53,15 @@ public function test_media_link_returns_media_path_without_cache_key_if_cache_bu
$this->assertIsString($path = $service->mediaLink('app.css'));
$this->assertEquals('media/app.css', $path);
}
+
+ public function test_inject_tailwind_config_returns_extracted_tailwind_config()
+ {
+ $service = new AssetService();
+ $this->assertIsString($config = $service->injectTailwindConfig());
+ $this->assertStringContainsString("darkMode: 'class'", $config);
+ $this->assertStringContainsString('theme: {', $config);
+ $this->assertStringContainsString('extend: {', $config);
+ $this->assertStringContainsString('typography: {', $config);
+ $this->assertStringNotContainsString('plugins', $config);
+ }
}
diff --git a/packages/framework/tests/Unit/Views/StylesComponentViewTest.php b/packages/framework/tests/Unit/Views/StylesComponentViewTest.php
index 7d3db097891..ec69173943e 100644
--- a/packages/framework/tests/Unit/Views/StylesComponentViewTest.php
+++ b/packages/framework/tests/Unit/Views/StylesComponentViewTest.php
@@ -4,6 +4,7 @@
namespace Hyde\Framework\Testing\Unit\Views;
+use function config;
use Hyde\Facades\Asset;
use Hyde\Hyde;
use Hyde\Testing\TestCase;
@@ -63,12 +64,18 @@ public function test_styles_can_be_pushed_to_the_component_styles_stack()
@push("styles")
foo bar
@endpush
-
+
@include("hyde::layouts.styles")'
)
);
}
+ public function test_component_renders_tailwind_play_cdn_link_when_enabled_in_config()
+ {
+ config(['hyde.use_play_cdn' => true]);
+ $this->assertStringContainsString('', $this->renderTestView());
+ }
+
public function test_component_renders_app_cdn_link_when_enabled_in_config()
{
config(['hyde.load_app_styles_from_cdn' => true]);