NextFs 0.4.0
See the version list below for details.
dotnet add package NextFs --version 0.4.0
NuGet\Install-Package NextFs -Version 0.4.0
<PackageReference Include="NextFs" Version="0.4.0" />
<PackageVersion Include="NextFs" Version="0.4.0" />
<PackageReference Include="NextFs" />
paket add NextFs --version 0.4.0
#r "nuget: NextFs, 0.4.0"
#:package NextFs@0.4.0
#addin nuget:?package=NextFs&version=0.4.0
#tool nuget:?package=NextFs&version=0.4.0
NextFs
NextFs is a thin Fable binding layer for writing Next.js App Router applications in F#.
The package stays close to native Next.js concepts instead of introducing a separate framework. If you already understand how a feature works in Next.js, the goal is that you can express the same shape in F# with minimal translation.
Start Here
If you are evaluating the repository for the first time, use this path:
- read Quickstart
- inspect the starter example
- learn the wrapper rules in Directives and wrappers
- use API reference as the lookup table
What It Covers
next/link,next/image,next/script,next/form,next/headnext/font/localand a generatednext/font/googlecatalog- App Router hooks and helpers from
next/navigation - request helpers from
next/headers NextRequest,NextResponse, and route handler helpers fromnext/serverproxy.jsconfig builders andNextFetchEvent- cache invalidation and cache directives from
next/cache - metadata, viewport, robots, sitemap, manifest, and image-metadata builders
ImageResponsebindings for Open Graph and icon generation- request/response cookie option builders
useLinkStatus,useReportWebVitals,after,userAgent,forbidden, andunauthorized- inline
Directive.useServer()andDirective.useCache()support - wrapper generation for file-level
'use client'and'use server'
Compatibility
NextFs:0.4.xnext:>= 15.0.0 < 17.0.0react:>= 18.2.0 < 20.0.0react-dom:>= 18.2.0 < 20.0.0- core Fable dependencies in this repo:
Fable.Core 4.5.0,Feliz 3.2.0
Install
dotnet add package NextFs
Your consuming Next.js app still provides the JavaScript runtime packages:
nextreactreact-dom
NextFs publishes Femto metadata for those packages, so a Fable consumer can check or resolve them with:
dotnet femto yourProject.fsproj
dotnet femto --resolve yourProject.fsproj
For repository work, restore local tools first:
dotnet tool restore
Quick Start
module App.Page
open Fable.Core
open Feliz
open NextFs
[<ReactComponent>]
let NavLink() =
Link.create [
Link.href "/dashboard"
prop.text "Dashboard"
]
[<ExportDefault>]
let Page() =
Html.main [
prop.children [
Html.h1 "Hello from Fable + Next.js"
NavLink()
]
]
Route handlers use JavaScript-shaped arguments and HTTP verb exports:
module App.Api.Posts
open Fable.Core
open Fable.Core.JsInterop
open NextFs
[<CompiledName("GET")>]
let get (request: NextRequest, ctx: RouteHandlerContext<{| slug: string |}>) =
async {
let! routeParams = Async.AwaitPromise ctx.``params``
return
ServerResponse.jsonWithInit
(createObj [
"slug" ==> routeParams.slug
"pathname" ==> request.nextUrl.pathname
])
(ResponseInit.create [
ResponseInit.status 200
])
}
|> Async.StartAsPromise
Server-side helpers follow the asynchronous shape of modern Next.js APIs:
module App.ServerPage
open Feliz
open NextFs
[<ExportDefault>]
let Page() =
async {
let! headers = Async.AwaitPromise(Server.headers())
let userAgent = headers.get("user-agent") |> Option.defaultValue "unknown"
return Html.pre userAgent
}
|> Async.StartAsPromise
Cache And Server Actions
NextFs now includes a baseline next/cache surface for App Router workflows:
Directive.useCache()Directive.useCachePrivate()Directive.useCacheRemote()Cache.cacheLifeProfileCache.cacheLifeCache.cacheTag/Cache.cacheTagsCache.revalidatePathCache.revalidateTagCache.updateTagCache.refreshCache.noStore
Example:
let loadNavigationLabels () =
Directive.useCache()
Cache.cacheLifeProfile CacheProfile.Hours
Cache.cacheTags [ "navigation"; "searches" ]
[| "Home"; "Search"; "Docs" |]
let saveSearch (_formData: obj) =
Directive.useServer()
Cache.updateTag "searches"
Cache.revalidatePath "/"
Cache.refresh()
()
Metadata And Special Files
NextFs now covers the parts of App Router you need to export from layouts and metadata files:
MetadataMetadataOpenGraphMetadataTwitterViewportMetadataRoute.RobotsMetadataRoute.SitemapEntryMetadataRoute.ManifestImageMetadataImageResponse
Example:
let metadata =
Metadata.create [
Metadata.titleTemplate (
MetadataTitle.create [
MetadataTitle.defaultValue "NextFs"
MetadataTitle.template "%s | NextFs"
]
)
Metadata.description "Next.js App Router bindings for F#."
Metadata.openGraph (
MetadataOpenGraph.create [
MetadataOpenGraph.title "NextFs"
MetadataOpenGraph.type' "website"
]
)
]
let viewport =
Viewport.create [
Viewport.themeColor "#111827"
Viewport.colorScheme "dark light"
]
For generated icon or Open Graph routes:
let generateImageMetadata() =
[|
ImageMetadata.create [
ImageMetadata.id "small"
ImageMetadata.contentType "image/png"
]
|]
Fonts, Proxy, And Cookies
The package now also covers the main App Router surfaces that typically force people back to handwritten JavaScript:
Font.localGoogleFont.Inter,GoogleFont.Roboto, and the rest of the generatednext/font/googlecatalogFontOptions,LocalFontSource, andFontDeclarationProxyConfig,ProxyMatcher,RouteHas, andNextFetchEventCookieOptionsfor request/response cookie mutation
Example:
let inter =
GoogleFont.Inter (
FontOptions.create [
FontOptions.subsets [ "latin" ]
FontOptions.display FontDisplay.Swap
FontOptions.variable "--font-inter"
]
)
let config =
ProxyConfig.create [
ProxyConfig.matcher "/dashboard/:path*"
]
More App Router Helpers
Beyond the baseline router/navigation APIs, NextFs now also includes:
Link.useLinkStatus()WebVitals.useReportWebVitals(...)Navigation.forbidden()Navigation.unauthorized()Navigation.unstableRethrow(...)Server.after(...)Server.userAgent(...)
These helpers are compile-smoked in samples/NextFs.Smoke.
App Router Directives And Wrappers
Inline directives work for function-level cases:
Directive.useServer()Directive.useCache()Directive.useCachePrivate()Directive.useCacheRemote()
File-level 'use client' and 'use server' directives are different. Fable emits imports first, so App Router entry files still need thin wrapper modules when the directive must appear at the top of the generated JavaScript file.
Generate them with:
node tools/nextfs-entry.mjs samples/nextfs.entries.json
For 'use server' wrappers, only named exports are allowed. The generator rejects default exports and export * for that case.
Repository Layout
src/NextFscontains the bindings packagesamples/NextFs.Smokecontains compile-smoke coverage of the package surfaceexamples/nextfs-startercontains a minimal end-to-end App Router starter, includinglayout,route, andproxyentries generated from F#tests/nextfs-entry.test.mjscovers the wrapper generatortools/nextfs-entry.mjsgenerates directive wrapper filestools/generate-google-font-bindings.mjsregenerates theGoogleFontbinding catalog from official Next.js type definitions
Examples And Docs
Validation
dotnet tool restore
dotnet femto --validate src/NextFs/NextFs.fsproj
node --test tests/*.mjs
dotnet build NextFs.slnx -v minimal
dotnet pack src/NextFs/NextFs.fsproj -c Release -o artifacts
node tools/nextfs-entry.mjs samples/nextfs.entries.json
node tools/nextfs-entry.mjs examples/nextfs-starter/nextfs.entries.json
NuGet Publishing
The repository includes .github/workflows/publish-nuget.yml, which publishes NextFs to nuget.org on manual dispatch or tag pushes matching v*.
Publishing uses NuGet Trusted Publishing through GitHub OIDC rather than a long-lived API key.
Package page:
Contributing
Contribution workflow and commit conventions are documented in CONTRIBUTING.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Fable.Core (>= 4.5.0)
- Feliz (>= 3.2.0)
- FSharp.Core (>= 10.1.201)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on NextFs:
| Package | Downloads |
|---|---|
|
NextFs.Dsl
High-level F# DSL for NextFs — computation expressions and async helpers for Next.js App Router. |
GitHub repositories
This package is not used by any popular GitHub repositories.