Índice de contenido
- Cómo funciona @vite() en Laravel
- Qué se entiende por “atributos personalizados @vite”
- ❌ Lo que NO funciona (y suele causar confusión)
- ❌ vite.config.js no controla atributos HTML
- ❌ @vite([...], ['async']) no existe en Laravel
- ✅ Forma correcta: atributos personalizados con Vite en Laravel
- Comparación con otros enfoques (Symfony y Vite puro)
- Plugins de Vite (Hackernoon)
- ¿Se pueden usar atributos condicionales por entorno?
- ¿Se pueden definir atributos por archivo?
- Conclusión
Cuando trabajamos con Laravel y Vite, es habitual usar la directiva @vite() para cargar nuestros archivos CSS y JavaScript. Sin embargo, una duda muy común es cómo personalizar los atributos HTML que se generan automáticamente en las etiquetas <script> y <link>.
En este artículo explico cómo funcionan realmente los atributos personalizados en @vite, qué se puede y qué no se puede hacer, y cuál es el enfoque correcto según el stack Laravel + Vite, evitando configuraciones incorrectas o confusas.
Cómo funciona @vite() en Laravel
Para cargar nuestros archivos CSS y JS en Laravel con vite mediante:
@vite(['resources/css/blog.css'])
@vite(['resources/js/blog.js'])En nuestros archivos blade; al momento del renderizado, obtenemos las etiquetas de HTML como:
<link rel="preload" as="style" href="https://www.desarrollolibre.net/build/assets/blog-6Y1hNTHC.css" />
<script type="module" src="https://www.desarrollolibre.net/build/assets/blog-Bdalpt8p.js"></script>Punto clave:
- Vite no renderiza estas etiquetas.
Laravel es quien genera el HTML final, usando la información producida por Vite.
Por eso, cualquier personalización de atributos HTML no se hace en vite.config.js, sino desde Laravel.
Qué se entiende por “atributos personalizados @vite”
Cuando hablamos de atributos personalizados, nos referimos a:
- async
- defer
- data-*
- integrity
- crossorigin
- atributos para Turbo, SEO o tracking
Ejemplo:
<script async data-turbo-track="reload"></script>
<link data-custom="value">❌ Lo que NO funciona (y suele causar confusión)
Antes de entrar en la solución correcta, es importante aclarar varios errores comunes que aparecen incluso en artículos técnicos.
❌ vite.config.js no controla atributos HTML
Opciones como:
- build.rollupOptions.output.assetFileNames
- plugins de Vite
- config condicional (defineConfig)
NO pueden añadir ni modificar atributos <script> o <link>.
Estas opciones solo afectan:
- nombres de archivos
- bundling
- plugins
- proxy
- optimización de build
❌ @vite([...], ['async']) no existe en Laravel
Laravel no permite pasar atributos HTML como segundo parámetro a @vite().
Cualquier ejemplo de este tipo es incorrecto:
@vite(['resources/js/app.js'], ['async']) ❌✅ Forma correcta: atributos personalizados con Vite en Laravel
Laravel expone una API oficial para modificar los atributos de las etiquetas generadas por @vite.
Esto se hace desde un Service Provider. Lo cual nos trae a la siguiente pregunta:
¿Qué pasa si quieres personalizar a nivel de atributos, por ejemplo, el async para los JavaScript?
Para ello, podemos agregar las modificaciones a nuestro provider:
app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Vite;
***
class AppServiceProvider extends ServiceProvider
{
***
public function boot(): void
{
Vite::useScriptTagAttributes([
'data-turbo-track' => 'reload',
'async' => true,
'integrity' => false,
]);
}
}Personalizar atributos globales de <link>:
Vite::useStyleTagAttributes([
'data-turbo-track' => 'reload',
]);HTML resultante:
<link rel="preload"
as="style"
href="/build/assets/blog.css"
data-turbo-track="reload">
<script type="module"
src="/build/assets/blog.js"
async
data-turbo-track="reload">
</script>- ✔️ Sin hacks
- ✔️ Sin plugins innecesarios
- ✔️ Totalmente soportado por Laravel
Por lo tanto, de esta forma es la que debemos de seguir para poder personalizar los atributos de las etiquetas de script y link con vite y Laravel.
Comparación con otros enfoques (Symfony y Vite puro)
- Symfony + Vite (Pentatrion)
- Symfony permite:
- Atributos globales
- Atributos locales
- Eventos (RenderAssetTagEvent)
- Symfony permite:
- Laravel no tiene eventos equivalentes, por lo que:
- El control es global
- No por asset individual
Esto explica por qué algunas guías de Symfony no aplican directamente a Laravel.
Plugins de Vite (Hackernoon)
Los plugins de Vite sirven para:
- Modificar el build
- Interceptar requests
- Generar archivos
- Middleware en dev server
No afectan al HTML generado por Laravel.
Son útiles solo si necesitas lógica de build, no atributos HTML.
¿Se pueden usar atributos condicionales por entorno?
Sí, pero desde Laravel, no desde Vite.
Ejemplo:
Vite::useScriptTagAttributes(
app()->isProduction()
? ['defer' => true]
: ['async' => true]
);¿Se pueden definir atributos por archivo?
❌ No de forma nativa.
Alternativas:
- renderizar scripts manualmente
- crear helpers personalizados
- usar @env en Blade
- separar entradas Vite
Conclusión
Si estás usando Laravel con Vite y necesitas atributos personalizados en @vite, la única forma correcta es hacerlo desde el facade Vite en Laravel.
- ❌ No desde vite.config.js
- ❌ No con plugins
- ❌ No pasando atributos a @vite()
✔️ Usa Vite::useScriptTagAttributes()
✔️ Usa Vite::useStyleTagAttributes()
Este enfoque es limpio, mantenible y compatible con futuras versiones.