Iwf Guide

Iwf Guide

Assets and Styling

Iwf vendors the framework assets used by the default shell and exposes helpers for app assets. Basecoat is the default styling target, while unstyled rendering is available when an app owns all markup and CSS.

1. Framework Assets

runApp mounts default framework assets under:

/__iwf/assets

The default shell uses fingerprinted versions of:

  • htmx
  • morphdom-swap support
  • Basecoat CSS/JS
  • Iwf client script

Generated apps do not rely on production CDNs for the default shell.

2. App Static Assets

Use embedded static assets:

appCss : StaticAsset
appCss =
  stylesheet "app.css" "body { font-family: sans-serif; }"

appWithAssetRoutes : Routes
appWithAssetRoutes =
  staticRoutes "/assets" [appCss] ++ appRoutes

Plain asset paths use revalidation cache headers and ETag.

Use fingerprinted assets for immutable caching:

cssHref : String
cssHref =
  fingerprintedAssetHref "/assets" appCss

assetRoutes : Routes
assetRoutes =
  fingerprintedStaticRoutes "/assets" [appCss]

3. Development Refresh

Add asset refresh during local development:

devLayout : PageLayout
devLayout context page =
  { pageHead := page.pageHead ++ [devAssetRefreshScript] } page

devPage : Html
devPage =
  fragment
    [ <title>Development</title>
    , <main id="main-content">
        <h1>Development</h1>
      </main>
    ]

The browser polls the asset version endpoint and reloads when the served asset bundle changes.

For browser reloads during local work, use:

  • devLiveReloadScript
  • devLiveReloadRoutes

4. Basecoat

Basecoat-oriented defaults are used by:

  • generated direct HTML starter
  • form helpers
  • submit buttons
  • flash messages
  • pagination
  • breadcrumbs
  • job dashboard

Use the app build to run Basecoat IDRX checking:

iwf build

For fully custom styling, return direct page HTML with render and configure shared shell attributes once with withPageLayout:

  • unstyledFormInput
  • unstyledFormErrors
  • unstyledSubmitButton

5. Tailwind and NPM

Iwf does not provide a first-class NPM/Yarn workflow. The canonical example has a Tailwind watcher because that app chooses to use it, not because the framework requires it. App-specific frontend tooling can live beside Iwf without becoming part of the framework contract.

Next

Read Navigation, Pagination, and SEO.