Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Semantic Ui Css Laravel Package

wangaz/laravel-semantic-ui-css

wangaz/laravel-semantic-ui-css integrates Semantic UI CSS into Laravel, making it easy to publish, configure, and load Semantic UI stylesheets and assets in your Blade views and frontend build.

Deep Wiki
Context7

Getting Started

Install and publish the assets

composer require wangaz/laravel-semantic-ui-css
php artisan vendor:publish --provider="Wangaz\SemanticUiCss\SemanticUiCssServiceProvider"

If you're on Laravel 5.5+ the service provider is auto-discovered. On Laravel ≤5.4 (which this package was built for), register it manually in config/app.php:

'providers' => [
    Wangaz\SemanticUiCss\SemanticUiCssServiceProvider::class,
],

Publishing copies the compiled Semantic UI CSS (semantic.min.css) and its themes/default/assets/fonts (Icons font) into public/. Confirm what actually landed before writing any markup:

php artisan vendor:publish --list     # find the exact tag
ls public/                            # note the real folder name (e.g. public/semantic or public/vendor/semantic)

Where to look first

  1. public/ — the published path is the single source of truth for your <link> href.
  2. The package's service provider (vendor/wangaz/laravel-semantic-ui-css/src/) — it's tiny; read publishes() to see source → destination mappings and tags.
  3. vendor/wangaz/laravel-semantic-ui-css/ for the bundled Semantic version (2.x era) — this determines which class names and components you can rely on.

First use case: a login screen

Add the stylesheet once in your base layout:

{{-- resources/views/layouts/app.blade.php --}}
<link rel="stylesheet" href="{{ asset('semantic/semantic.min.css') }}">

Then the form is pure Semantic UI classes — no build step, no config:

<form class="ui form" method="POST" action="{{ route('login') }}">
    @csrf
    <div class="field @error('email') error @enderror">
        <label>E-mail</label>
        <input type="email" name="email" value="{{ old('email') }}" placeholder="[email protected]">
    </div>
    <div class="field @error('password') error @enderror">
        <label>Password</label>
        <input type="password" name="password">
    </div>
    <button class="ui primary button" type="submit">Sign in</button>
</form>

That's the whole loop: publish once, asset() once, then write Semantic class names.

Implementation Patterns

Wrap the asset in a layout partial, not per-view

Keep the <link> in one place and let every view extend it. Because the package ships a single compiled stylesheet, there's nothing to concatenate — just load it before your own overrides:

<link rel="stylesheet" href="{{ asset('semantic/semantic.min.css') }}">
<link rel="stylesheet" href="{{ asset('css/app.css') }}">   {{-- your overrides, always last --}}

Abstract Semantic classes into Blade components

Semantic UI is verbose (ui secondary pointing menu, ui inverted segment). If you're on Laravel 7+, wrap the recurring ones so class churn happens in one file:

{{-- resources/views/components/ui/button.blade.php --}}
<button {{ $attributes->merge(['class' => 'ui ' . ($variant ?? 'basic') . ' button']) }}>
    {{ $slot }}
</button>
<x-ui.button variant="primary">Save changes</x-ui.button>

This also gives you an escape hatch later if you migrate from Semantic to Tailwind/Bootstrap — you change the component, not 200 views.

Menus that reflect the current route

Semantic's active class maps cleanly onto Laravel's route helpers:

<div class="ui secondary pointing menu">
    <a class="item {{ request()->routeIs('dashboard') ? 'active' : '' }}"
       href="{{ route('dashboard') }}">Dashboard</a>
    <a class="item {{ request()->routeIs('projects.*') ? 'active' : '' }}"
       href="{{ route('projects.index') }}">Projects</a>
</div>

Flash messages and validation errors as Semantic messages

@if (session('status'))
    <div class="ui positive message">
        <i class="close icon"></i>
        <div class="header">{{ session('status') }}</div>
    </div>
@endif

@error('email')
    <div class="ui pointing red basic label">{{ $message }}</div>
@enderror

Layouts: use Semantic's grid, but don't fight it

ui stackable grid + column is the workhorse for admin screens and gives you mobile behaviour for free. Reserve custom CSS for things Semantic genuinely doesn't cover; bolting flexbox hacks onto .ui.grid tends to break its negative-margin gutters.

Pagination needs a custom view

Laravel's default paginator markup is Tailwind/Bootstrap-shaped and will render as an unstyled list on a Semantic page. Publish the pagination views and rewrite pagination::semantic-ui, then set it as your default:

// app/Providers/AppServiceProvider.php
use Illuminate\Pagination\Paginator;

public function boot(): void
{
    Paginator::defaultView('pagination::semantic-ui');
}

Use ui pagination menu / item / active item / disabled item classes inside that view.

If you use Mix or Vite, treat these assets as static

Don't try to @vite the published CSS — it lives in public/ and is already minified. At most, copy it into your build for fingerprinting:

// vite.config.js
import { defineConfig } from 'vite';
// ...or simply leave it alone and reference it with asset()

The pragmatic answer on modern stacks: keep asset('semantic/semantic.min.css') and skip the bundler entirely for this file.

Gotchas and Tips

This is CSS only — interactive components won't work out of the box. The package name is literal. Dropdowns, modals, tabs, accordions, and the searchable select all need Semantic UI's JavaScript, which requires jQuery. If you need behaviour, either include semantic.min.js plus jQuery from a CDN, or implement the behaviour with Alpine.js/Livewire against Semantic's expected class toggles (active, visible, .ui.modal). Plan for this early — it's the most common surprise.

Check the published font path before shipping. Semantic's icon font is loaded relative to the CSS via themes/default/assets/fonts/*. If your publish destination flattens the directory, every <i class="user icon"> becomes an empty box. Verify with devtools → Network that outline-icons.woff2 / icons.woff2 return 200. If they 404, either restore the directory structure or override @font-face in your own CSS.

The package is essentially frozen (last release 2017). Expect Composer conflicts on Laravel 9+. If composer require fails on illuminate/support constraints, don't force it into composer.json — the honest options are (a) vendor the CSS files into resources/ or public/ manually and drop the dependency, or (b) fork the package and widen the constraint. Since all it does is copy files, vendoring loses you almost nothing and removes an unmaintained dependency from your lockfile.

Know what vendor:publish will overwrite. Published assets are static copies — they do not track package updates, and re-publishing with --force will silently clobber any hand-edits you made in public/. Never edit the published Semantic files. Put every tweak in your own public/css/app.css loaded afterwards.

No theming, no variables. There's no Node/Sass pipeline here, so Semantic's theme.config and site.variables customisation path is unavailable. You get the default theme. Override at the CSS level with specificity (body .ui.primary.button { ... }) or, if you need real theming, this package is the wrong tool — use the npm build.

Decide whether to commit public/ assets. Because publishing is a one-time, non-idempotent step, either commit the published files (simplest for CI/deploy, guarantees parity across environments) or make vendor:publish --force part of your deploy script. Mixing the two — committed assets plus a deploy that republishes — creates confusing overwrite bugs.

Versioning/cache-busting is your job. asset() won't fingerprint these files. Append a manual query string or a config value when you upgrade Semantic so browsers don't serve a stale stylesheet:

<link rel="stylesheet" href="{{ asset('semantic/semantic.min.css') }}?v={{ config('app.asset_version') }}">

Extension points are limited — and that's fine. The provider only publishes files; there are no config knobs, Blade directives, or view components shipped. Your extension surface is: your own layout, your own CSS loaded last, and Blade components wrapping Semantic classes. Debug issues in that order — a class that "isn't working" is almost always being overridden by app.css or the wrong published path, not a package bug. Run php artisan view:clear and hard-reload before chasing anything deeper.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager