+
+
+
+
+[![Discord](https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7)](https://gofiber.io/discord)
+![Test](https://github.com/gofiber/contrib/workflows/Tests/badge.svg)
+![Security](https://github.com/gofiber/contrib/workflows/Security/badge.svg)
+![Linter](https://github.com/gofiber/contrib/workflows/Linter/badge.svg)
+
+Repository for third party middlewares with dependencies.
+
+
+
+## 📑 Middleware Implementations
+
+* [Casbin](./casbin/README.md)
+* [Fgprof](./fgprof/README.md)
+* [Fiberi18n](./fiberi18n/README.md)
+* [Fibersentry](./fibersentry/README.md)
+* [Fiberzap](./fiberzap/README.md)
+* [Fiberzerolog](./fiberzerolog/README.md)
+* [HCaptcha](./hcaptcha/README.md)
+* [JWT](./jwt/README.md)
+* [Loadshed](./loadshed/README.md)
+* [NewRelic](./fibernewrelic/README.md)
+* [Open Policy Agent](./opafiber/README.md)
+* [Otelfiber (OpenTelemetry)](./otelfiber/README.md)
+* [Paseto](./paseto/README.md)
+* [Socket.io](./socketio/README.md)
+* [Swagger](./swagger/README.md)
+* [Websocket](./websocket/README.md)
diff --git a/contrib_versioned_docs/version-hcaptcha_v0.x.x/casbin/README.md b/contrib_versioned_docs/version-hcaptcha_v0.x.x/casbin/README.md
new file mode 100644
index 00000000000..6462cc0294a
--- /dev/null
+++ b/contrib_versioned_docs/version-hcaptcha_v0.x.x/casbin/README.md
@@ -0,0 +1,155 @@
+---
+id: casbin
+---
+
+# Casbin
+
+![Release](https://img.shields.io/github/v/tag/gofiber/contrib?filter=casbin*)
+[![Discord](https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7)](https://gofiber.io/discord)
+![Test](https://github.com/gofiber/contrib/workflows/Tests/badge.svg)
+![Security](https://github.com/gofiber/contrib/workflows/Security/badge.svg)
+![Linter](https://github.com/gofiber/contrib/workflows/Linter/badge.svg)
+
+Casbin middleware for Fiber.
+
+**Note: Requires Go 1.18 and above**
+
+## Install
+```
+go get -u github.com/gofiber/fiber/v2
+go get -u github.com/gofiber/contrib/casbin
+```
+choose an adapter from [here](https://casbin.org/docs/en/adapters)
+```
+go get -u github.com/casbin/xorm-adapter
+```
+
+## Signature
+```go
+casbin.New(config ...casbin.Config) *casbin.Middleware
+```
+
+## Config
+
+| Property | Type | Description | Default |
+|:--------------|:--------------------------|:-----------------------------------------|:--------------------------------------------------------------------|
+| ModelFilePath | `string` | Model file path | `"./model.conf"` |
+| PolicyAdapter | `persist.Adapter` | Database adapter for policies | `./policy.csv` |
+| Enforcer | `*casbin.Enforcer` | Custom casbin enforcer | `Middleware generated enforcer using ModelFilePath & PolicyAdapter` |
+| Lookup | `func(*fiber.Ctx) string` | Look up for current subject | `""` |
+| Unauthorized | `func(*fiber.Ctx) error` | Response body for unauthorized responses | `Unauthorized` |
+| Forbidden | `func(*fiber.Ctx) error` | Response body for forbidden responses | `Forbidden` |
+
+### Examples
+- [Gorm Adapter](https://github.com/svcg/-fiber_casbin_demo)
+- [File Adapter](https://github.com/gofiber/contrib/casbin/tree/master/example)
+
+## CustomPermission
+
+```go
+package main
+
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/contrib/casbin"
+ _ "github.com/go-sql-driver/mysql"
+ "github.com/casbin/xorm-adapter/v2"
+)
+
+func main() {
+ app := fiber.New()
+
+ authz := casbin.New(casbin.Config{
+ ModelFilePath: "path/to/rbac_model.conf",
+ PolicyAdapter: xormadapter.NewAdapter("mysql", "root:@tcp(127.0.0.1:3306)/"),
+ Lookup: func(c *fiber.Ctx) string {
+ // fetch authenticated user subject
+ },
+ })
+
+ app.Post("/blog",
+ authz.RequiresPermissions([]string{"blog:create"}, casbin.WithValidationRule(casbin.MatchAllRule)),
+ func(c *fiber.Ctx) error {
+ // your handler
+ },
+ )
+
+ app.Delete("/blog/:id",
+ authz.RequiresPermissions([]string{"blog:create", "blog:delete"}, casbin.WithValidationRule(casbin.AtLeastOneRule)),
+ func(c *fiber.Ctx) error {
+ // your handler
+ },
+ )
+
+ app.Listen(":8080")
+}
+```
+
+## RoutePermission
+
+```go
+package main
+
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/contrib/casbin"
+ _ "github.com/go-sql-driver/mysql"
+ "github.com/casbin/xorm-adapter/v2"
+)
+
+func main() {
+ app := fiber.New()
+
+ authz := casbin.New(casbin.Config{
+ ModelFilePath: "path/to/rbac_model.conf",
+ PolicyAdapter: xormadapter.NewAdapter("mysql", "root:@tcp(127.0.0.1:3306)/"),
+ Lookup: func(c *fiber.Ctx) string {
+ // fetch authenticated user subject
+ },
+ })
+
+ // check permission with Method and Path
+ app.Post("/blog",
+ authz.RoutePermission(),
+ func(c *fiber.Ctx) error {
+ // your handler
+ },
+ )
+
+ app.Listen(":8080")
+}
+```
+
+## RoleAuthorization
+
+```go
+package main
+
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/contrib/casbin"
+ _ "github.com/go-sql-driver/mysql"
+ "github.com/casbin/xorm-adapter/v2"
+)
+
+func main() {
+ app := fiber.New()
+
+ authz := casbin.New(casbin.Config{
+ ModelFilePath: "path/to/rbac_model.conf",
+ PolicyAdapter: xormadapter.NewAdapter("mysql", "root:@tcp(127.0.0.1:3306)/"),
+ Lookup: func(c *fiber.Ctx) string {
+ // fetch authenticated user subject
+ },
+ })
+
+ app.Put("/blog/:id",
+ authz.RequiresRoles([]string{"admin"}),
+ func(c *fiber.Ctx) error {
+ // your handler
+ },
+ )
+
+ app.Listen(":8080")
+}
+```
diff --git a/contrib_versioned_docs/version-hcaptcha_v0.x.x/fgprof/README.md b/contrib_versioned_docs/version-hcaptcha_v0.x.x/fgprof/README.md
new file mode 100644
index 00000000000..74a87f1f259
--- /dev/null
+++ b/contrib_versioned_docs/version-hcaptcha_v0.x.x/fgprof/README.md
@@ -0,0 +1,59 @@
+---
+id: fgprof
+---
+
+# Fgprof
+
+![Release](https://img.shields.io/github/v/tag/gofiber/contrib?filter=fgprof*)
+[![Discord](https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7)](https://gofiber.io/discord)
+![Test](https://github.com/gofiber/contrib/workflows/Tests/badge.svg)
+![Security](https://github.com/gofiber/contrib/workflows/Security/badge.svg)
+![Linter](https://github.com/gofiber/contrib/workflows/Linter/badge.svg)
+
+[fgprof](https://github.com/felixge/fgprof) support for Fiber.
+
+**Note: Requires Go 1.19 and above**
+
+## Install
+
+This middleware supports Fiber v2.
+
+Using fgprof to profiling your Fiber app.
+
+```
+go get -u github.com/gofiber/fiber/v2
+go get -u github.com/gofiber/contrib/fgprof
+```
+
+## Config
+
+| Property | Type | Description | Default |
+|----------|---------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|---------|
+| Next | `func(c *fiber.Ctx) bool` | A function to skip this middleware when returned `true`. | `nil` |
+| Prefix | `string`. | Prefix defines a URL prefix added before "/debug/fgprof". Note that it should start with (but not end with) a slash. Example: "/federated-fiber" | `""` |
+
+## Example
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gofiber/contrib/fgprof"
+ "github.com/gofiber/fiber/v2"
+)
+
+func main() {
+ app := fiber.New()
+ app.Use(fgprof.New())
+ app.Get("/", func(c *fiber.Ctx) error {
+ return c.SendString("OK")
+ })
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+```bash
+go tool pprof -http=:8080 http://localhost:3000/debug/fgprof
+```
diff --git a/contrib_versioned_docs/version-hcaptcha_v0.x.x/fiberi18n/README.md b/contrib_versioned_docs/version-hcaptcha_v0.x.x/fiberi18n/README.md
new file mode 100644
index 00000000000..6085548ab1b
--- /dev/null
+++ b/contrib_versioned_docs/version-hcaptcha_v0.x.x/fiberi18n/README.md
@@ -0,0 +1,88 @@
+---
+id: fiberi18n
+---
+
+# Fiberi18n
+
+![Release](https://img.shields.io/github/v/tag/gofiber/contrib?filter=fiberi18n*)
+[![Discord](https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7)](https://gofiber.io/discord)
+![Test](https://github.com/gofiber/contrib/workflows/Tests/badge.svg)
+![Security](https://github.com/gofiber/contrib/workflows/Security/badge.svg)
+![Linter](https://github.com/gofiber/contrib/workflows/Linter/badge.svg)
+
+[go-i18n](https://github.com/nicksnyder/go-i18n) support for Fiber.
+
+**Note: Requires Go 1.18 and above**
+
+## Install
+
+This middleware supports Fiber v2.
+
+```
+go get -u github.com/gofiber/fiber/v2
+go get -u github.com/gofiber/contrib/fiberi18n/v2
+```
+
+## Signature
+
+| Name | Signature | Description |
+|--------------|----------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
+| New | `New(config ...*fiberi18n.Config) fiber.Handler` | Create a new fiberi18n middleware handler |
+| Localize | `Localize(ctx *fiber.Ctx, params interface{}) (string, error)` | Localize returns a localized message. param is one of these type: messageID, *i18n.LocalizeConfig |
+| MustLocalize | `MustLocalize(ctx *fiber.Ctx, params interface{}) string` | MustLocalize is similar to Localize, except it panics if an error happens. param is one of these type: messageID, *i18n.LocalizeConfig |
+
+## Config
+
+| Property | Type | Description | Default |
+|------------------|---------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|
+| Next | `func(c *fiber.Ctx) bool` | A function to skip this middleware when returned `true`. | `nil` |
+| RootPath | `string` | The i18n template folder path. | `"./example/localize"` |
+| AcceptLanguages | `[]language.Tag` | A collection of languages that can be processed. | `[]language.Tag{language.Chinese, language.English}` |
+| FormatBundleFile | `string` | The type of the template file. | `"yaml"` |
+| DefaultLanguage | `language.Tag` | The default returned language type. | `language.English` |
+| Loader | `Loader` | The implementation of the Loader interface, which defines how to read the file. We provide both os.ReadFile and embed.FS.ReadFile. | `LoaderFunc(os.ReadFile)` |
+| UnmarshalFunc | `i18n.UnmarshalFunc` | The function used for decoding template files. | `yaml.Unmarshal` |
+| LangHandler | `func(ctx *fiber.Ctx, defaultLang string) string` | Used to get the kind of language handled by *fiber.Ctx and defaultLang. | Retrieved from the request header `Accept-Language` or query parameter `lang`. |
+
+## Example
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gofiber/contrib/fiberi18n/v2"
+ "github.com/gofiber/fiber/v2"
+ "github.com/nicksnyder/go-i18n/v2/i18n"
+ "golang.org/x/text/language"
+)
+
+func main() {
+ app := fiber.New()
+ app.Use(
+ fiberi18n.New(&fiberi18n.Config{
+ RootPath: "./example/localize",
+ AcceptLanguages: []language.Tag{language.Chinese, language.English},
+ DefaultLanguage: language.Chinese,
+ }),
+ )
+ app.Get("/", func(c *fiber.Ctx) error {
+ localize, err := fiberi18n.Localize(c, "welcome")
+ if err != nil {
+ return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
+ }
+ return c.SendString(localize)
+ })
+ app.Get("/:name", func(ctx *fiber.Ctx) error {
+ return ctx.SendString(fiberi18n.MustLocalize(ctx, &i18n.LocalizeConfig{
+ MessageID: "welcomeWithName",
+ TemplateData: map[string]string{
+ "name": ctx.Params("name"),
+ },
+ }))
+ })
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
diff --git a/contrib_versioned_docs/version-hcaptcha_v0.x.x/fibernewrelic/README.md b/contrib_versioned_docs/version-hcaptcha_v0.x.x/fibernewrelic/README.md
new file mode 100644
index 00000000000..28f954ce983
--- /dev/null
+++ b/contrib_versioned_docs/version-hcaptcha_v0.x.x/fibernewrelic/README.md
@@ -0,0 +1,112 @@
+---
+id: fibernewrelic
+---
+
+# Fibernewrelic
+
+![Release](https://img.shields.io/github/v/tag/gofiber/contrib?filter=fibernewrelic*)
+[![Discord](https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7)](https://gofiber.io/discord)
+![Test](https://github.com/gofiber/contrib/workflows/Tests/badge.svg)
+![Security](https://github.com/gofiber/contrib/workflows/Security/badge.svg)
+![Linter](https://github.com/gofiber/contrib/workflows/Linter/badge.svg)
+
+[NewRelic](https://github.com/newrelic/go-agent) support for Fiber.
+
+**Note: Requires Go 1.18 and above**
+
+## Install
+
+```
+go get -u github.com/gofiber/fiber/v2
+go get -u github.com/gofiber/contrib/fibernewrelic
+```
+
+## Signature
+
+```go
+fibernewrelic.New(config fibernewrelic.Config) fiber.Handler
+```
+
+## Config
+
+| Property | Type | Description | Default |
+|:------------------|:-----------------|:---------------------------------------|:---------------|
+| License | `string` | Required - New Relic License Key | `""` |
+| AppName | `string` | New Relic Application Name | `fiber-api` |
+| Enabled | `bool` | Enable/Disable New Relic | `false` |
+| ~~TransportType~~ | ~~`string`~~ | ~~Can be HTTP or HTTPS~~ (Deprecated) | ~~`"HTTP"`~~ |
+| Application | `Application` | Existing New Relic App | `nil` |
+| ErrorStatusCodeHandler | `func(c *fiber.Ctx, err error) int` | If you want to change newrelic status code, you can use it. | `DefaultErrorStatusCodeHandler` |
+
+## Usage
+
+```go
+package main
+
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/contrib/fibernewrelic"
+)
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/", func(ctx *fiber.Ctx) error {
+ return ctx.SendStatus(200)
+ })
+
+ cfg := fibernewrelic.Config{
+ License: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ AppName: "MyCustomApi",
+ Enabled: true,
+ }
+
+ app.Use(fibernewrelic.New(cfg))
+
+ app.Listen(":8080")
+}
+```
+
+## Usage with existing New Relic application
+
+```go
+package main
+
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/contrib/fibernewrelic"
+ "github.com/newrelic/go-agent/v3/newrelic"
+)
+
+func main() {
+ newrelicApp, err := newrelic.NewApplication(
+ newrelic.ConfigAppName("MyCustomApi"),
+ newrelic.ConfigLicense("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
+ newrelic.ConfigEnabled(true),
+ )
+
+ app := fiber.New()
+
+ app.Get("/", func(ctx *fiber.Ctx) error {
+ return ctx.SendStatus(200)
+ })
+
+ app.Get("/foo", func(ctx *fiber.Ctx) error {
+ txn := newrelic.FromContext(ctx)
+ segment := txn.StartSegment("foo segment")
+ defer segment.End()
+
+ // do foo
+
+ return nil
+ })
+
+ cfg := fibernewrelic.Config{
+ Application: newrelicApp,
+ }
+
+ app.Use(fibernewrelic.New(cfg))
+
+ app.Listen(":8080")
+}
+```
diff --git a/contrib_versioned_docs/version-hcaptcha_v0.x.x/fibersentry/README.md b/contrib_versioned_docs/version-hcaptcha_v0.x.x/fibersentry/README.md
new file mode 100644
index 00000000000..6291441d9e3
--- /dev/null
+++ b/contrib_versioned_docs/version-hcaptcha_v0.x.x/fibersentry/README.md
@@ -0,0 +1,126 @@
+---
+id: fibersentry
+---
+
+# Fibersentry
+
+![Release](https://img.shields.io/github/v/tag/gofiber/contrib?filter=fibersentry*)
+[![Discord](https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7)](https://gofiber.io/discord)
+![Test](https://github.com/gofiber/contrib/workflows/Tests/badge.svg)
+![Security](https://github.com/gofiber/contrib/workflows/Security/badge.svg)
+![Linter](https://github.com/gofiber/contrib/workflows/Linter/badge.svg)
+
+[Sentry](https://sentry.io/) support for Fiber.
+
+**Note: Requires Go 1.18 and above**
+
+## Install
+
+This middleware supports Fiber v2.
+
+```
+go get -u github.com/gofiber/fiber/v2
+go get -u github.com/gofiber/contrib/fibersentry
+go get -u github.com/getsentry/sentry-go
+```
+
+## Signature
+
+```
+fibersentry.New(config ...fibersentry.Config) fiber.Handler
+```
+
+## Config
+
+| Property | Type | Description | Default |
+|:----------------|:----------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------|
+| Repanic | `bool` | Repanic configures whether Sentry should repanic after recovery. Set to true, if [Recover](https://github.com/gofiber/fiber/tree/master/middleware/recover) middleware is used. | `false` |
+| WaitForDelivery | `bool` | WaitForDelivery configures whether you want to block the request before moving forward with the response. If [Recover](https://github.com/gofiber/fiber/tree/master/middleware/recover) middleware is used, it's safe to either skip this option or set it to false. | `false` |
+| Timeout | `time.Duration` | Timeout for the event delivery requests. | `time.Second * 2` |
+
+## Usage
+
+`fibersentry` attaches an instance of `*sentry.Hub` (https://godoc.org/github.com/getsentry/sentry-go#Hub) to the request's context, which makes it available throughout the rest of the request's lifetime.
+You can access it by using the `fibersentry.GetHubFromContext()` method on the context itself in any of your proceeding middleware and routes.
+And it should be used instead of the global `sentry.CaptureMessage`, `sentry.CaptureException`, or any other calls, as it keeps the separation of data between the requests.
+
+**Keep in mind that `*sentry.Hub` won't be available in middleware attached before to `fibersentry`!**
+
+```go
+package main
+
+import (
+ "fmt"
+ "log"
+
+ "github.com/getsentry/sentry-go"
+ "github.com/gofiber/contrib/fibersentry"
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/utils"
+)
+
+func main() {
+ _ = sentry.Init(sentry.ClientOptions{
+ Dsn: "",
+ BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
+ if hint.Context != nil {
+ if c, ok := hint.Context.Value(sentry.RequestContextKey).(*fiber.Ctx); ok {
+ // You have access to the original Context if it panicked
+ fmt.Println(utils.ImmutableString(c.Hostname()))
+ }
+ }
+ fmt.Println(event)
+ return event
+ },
+ Debug: true,
+ AttachStacktrace: true,
+ })
+
+ app := fiber.New()
+
+ app.Use(fibersentry.New(fibersentry.Config{
+ Repanic: true,
+ WaitForDelivery: true,
+ }))
+
+ enhanceSentryEvent := func(c *fiber.Ctx) error {
+ if hub := fibersentry.GetHubFromContext(c); hub != nil {
+ hub.Scope().SetTag("someRandomTag", "maybeYouNeedIt")
+ }
+ return c.Next()
+ }
+
+ app.All("/foo", enhanceSentryEvent, func(c *fiber.Ctx) error {
+ panic("y tho")
+ })
+
+ app.All("/", func(c *fiber.Ctx) error {
+ if hub := fibersentry.GetHubFromContext(c); hub != nil {
+ hub.WithScope(func(scope *sentry.Scope) {
+ scope.SetExtra("unwantedQuery", "someQueryDataMaybe")
+ hub.CaptureMessage("User provided unwanted query string, but we recovered just fine")
+ })
+ }
+ return c.SendStatus(fiber.StatusOK)
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+## Accessing Context in `BeforeSend` callback
+
+```go
+sentry.Init(sentry.ClientOptions{
+ Dsn: "your-public-dsn",
+ BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
+ if hint.Context != nil {
+ if c, ok := hint.Context.Value(sentry.RequestContextKey).(*fiber.Ctx); ok {
+ // You have access to the original Context if it panicked
+ fmt.Println(c.Hostname())
+ }
+ }
+ return event
+ },
+})
+```
diff --git a/contrib_versioned_docs/version-hcaptcha_v0.x.x/fiberzap/README.md b/contrib_versioned_docs/version-hcaptcha_v0.x.x/fiberzap/README.md
new file mode 100644
index 00000000000..8cbf80517b6
--- /dev/null
+++ b/contrib_versioned_docs/version-hcaptcha_v0.x.x/fiberzap/README.md
@@ -0,0 +1,120 @@
+---
+id: fiberzap
+---
+
+# Fiberzap
+
+![Release](https://img.shields.io/github/v/tag/gofiber/contrib?filter=fiberzap*)
+[![Discord](https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7)](https://gofiber.io/discord)
+![Test](https://github.com/gofiber/contrib/workflows/Tests/badge.svg)
+![Security](https://github.com/gofiber/contrib/workflows/Security/badge.svg)
+![Linter](https://github.com/gofiber/contrib/workflows/Linter/badge.svg)
+
+[Zap](https://github.com/uber-go/zap) logging support for Fiber.
+
+**Note: Requires Go 1.19 and above**
+
+## Install
+
+This middleware supports Fiber v2.
+
+```
+go get -u github.com/gofiber/fiber/v2
+go get -u github.com/gofiber/contrib/fiberzap/v2
+go get -u go.uber.org/zap
+```
+
+### Signature
+
+```go
+fiberzap.New(config ...fiberzap.Config) fiber.Handler
+```
+
+### Config
+
+| Property | Type | Description | Default |
+| :--------- | :------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------- |
+| Next | `func(*Ctx) bool` | Define a function to skip this middleware when returned true | `nil` |
+| Logger | `*zap.Logger` | Add custom zap logger. | `zap.NewDevelopment()` |
+| Fields | `[]string` | Add fields what you want see. | `[]string{"latency", "status", "method", "url"}` |
+| FieldsFunc | `[]zap.Field` | Define a function to add custom fields. | `nil` |
+| Messages | `[]string` | Custom response messages. | `[]string{"Server error", "Client error", "Success"}` |
+| Levels | `[]zapcore.Level` | Custom response levels. | `[]zapcore.Level{zapcore.ErrorLevel, zapcore.WarnLevel, zapcore.InfoLevel}` |
+| SkipURIs | `[]string` | Skip logging these URI. | `[]string{}` |
+| GetResBody | func(c \*fiber.Ctx) []byte | Define a function to get response body when return non-nil. eg: When use compress middleware, resBody is unreadable. you can set GetResBody func to get readable resBody. | `nil` |
+
+### Example
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/contrib/fiberzap/v2"
+ "go.uber.org/zap"
+)
+
+func main() {
+ app := fiber.New()
+ logger, _ := zap.NewProduction()
+
+ app.Use(fiberzap.New(fiberzap.Config{
+ Logger: logger,
+ }))
+
+ app.Get("/", func (c *fiber.Ctx) error {
+ return c.SendString("Hello, World!")
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+## NewLogger
+
+### Signature
+
+```go
+fiberzap.NewLogger(config ...fiberzap.LoggerConfig) *fiberzap.LoggerConfig
+```
+
+### LoggerConfig
+
+| Property | Type | Description | Default |
+| :---------- | :------------- | :------------------------------------------------------------------------------------------------------- | :----------------------------- |
+| CoreConfigs | `[]CoreConfig` | Define Config for zapcore | `fiberzap.LoggerConfigDefault` |
+| SetLogger | `*zap.Logger` | Add custom zap logger. if not nil, `ZapOptions`, `CoreConfigs`, `SetLevel`, `SetOutput` will be ignored. | `nil` |
+| ExtraKeys | `[]string` | Allow users log extra values from context. | `[]string{}` |
+| ZapOptions | `[]zap.Option` | Allow users to configure the zap.Option supplied by zap. | `[]zap.Option{}` |
+
+### Example
+
+```go
+package main
+
+import (
+ "context"
+ "github.com/gofiber/contrib/fiberzap/v2"
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/log"
+)
+
+func main() {
+ app := fiber.New()
+ log.SetLogger(fiberzap.NewLogger(fiberzap.LoggerConfig{
+ ExtraKeys: []string{"request_id"},
+ }))
+ app.Use(func(c *fiber.Ctx) error {
+ ctx := context.WithValue(c.UserContext(), "request_id", "123")
+ c.SetUserContext(ctx)
+ return c.Next()
+ })
+ app.Get("/", func(c *fiber.Ctx) error {
+ log.WithContext(c.UserContext()).Info("Hello, World!")
+ return c.SendString("Hello, World!")
+ })
+ log.Fatal(app.Listen(":3000"))
+}
+```
diff --git a/contrib_versioned_docs/version-hcaptcha_v0.x.x/fiberzerolog/README.md b/contrib_versioned_docs/version-hcaptcha_v0.x.x/fiberzerolog/README.md
new file mode 100644
index 00000000000..46e7f5a5612
--- /dev/null
+++ b/contrib_versioned_docs/version-hcaptcha_v0.x.x/fiberzerolog/README.md
@@ -0,0 +1,74 @@
+---
+id: fiberzerolog
+---
+
+# Fiberzerolog
+
+![Release](https://img.shields.io/github/v/tag/gofiber/contrib?filter=fiberzerolog*)
+[![Discord](https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7)](https://gofiber.io/discord)
+![Test](https://github.com/gofiber/contrib/workflows/Tests/badge.svg)
+![Security](https://github.com/gofiber/contrib/workflows/Security/badge.svg)
+![Linter](https://github.com/gofiber/contrib/workflows/Linter/badge.svg)
+
+[Zerolog](https://zerolog.io/) logging support for Fiber.
+
+**Note: Requires Go 1.18 and above**
+
+## Install
+
+This middleware supports Fiber v2.
+
+```sh
+go get -u github.com/gofiber/fiber/v2
+go get -u github.com/gofiber/contrib/fiberzerolog
+go get -u github.com/rs/zerolog/log
+```
+
+## Signature
+
+```go
+fiberzerolog.New(config ...fiberzerolog.Config) fiber.Handler
+```
+
+## Config
+
+| Property | Type | Description | Default |
+|:--------------|:-------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------|
+| Next | `func(*Ctx) bool` | Define a function to skip this middleware when returned true | `nil` |
+| Logger | `*zerolog.Logger` | Add custom zerolog logger. | `zerolog.New(os.Stderr).With().Timestamp().Logger()` |
+| GetLogger | `func(*fiber.Ctx) zerolog.Logger` | Get custom zerolog logger, if it's defined the returned logger will replace the `Logger` value. | `nil` |
+| Fields | `[]string` | Add fields what you want see. | `[]string{"latency", "status", "method", "url", "error"}` |
+| WrapHeaders | bool | Wrap headers to dictionary. If false: `{"method":"POST", "header-key":"header value"}` If true: `{"method":"POST", "reqHeaders": {"header-key":"header value"}}` | `false` |
+| FieldsSnakeCase | bool | Use snake case for fields: FieldResBody, FieldQueryParams, FieldBytesReceived, FieldBytesSent, FieldRequestId, FieldReqHeaders, FieldResHeaders. If false: `{"method":"POST", "resBody":"v", "queryParams":"v"}` If true: `{"method":"POST", "res_body":"v", "query_params":"v"}` | `false` |
+| Messages | `[]string` | Custom response messages. | `[]string{"Server error", "Client error", "Success"}` |
+| Levels | `[]zerolog.Level` | Custom response levels. | `[]zerolog.Level{zerolog.ErrorLevel, zerolog.WarnLevel, zerolog.InfoLevel}` |
+| SkipURIs | `[]string` | Skip logging these URI. | `[]string{}` |
+| GetResBody | func(c *fiber.Ctx) []byte | Define a function to get response body when return non-nil. eg: When use compress middleware, resBody is unreadable. you can set GetResBody func to get readable resBody. | `nil` |
+## Example
+
+```go
+package main
+
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/contrib/fiberzerolog"
+ "github.com/rs/zerolog"
+)
+
+func main() {
+ app := fiber.New()
+ logger := zerolog.New(os.Stderr).With().Timestamp().Logger()
+
+ app.Use(fiberzerolog.New(fiberzerolog.Config{
+ Logger: &logger,
+ }))
+
+ app.Get("/", func (c *fiber.Ctx) error {
+ return c.SendString("Hello, World!")
+ })
+
+ if err := app.Listen(":3000"); err != nil {
+ logger.Fatal().Err(err).Msg("Fiber app error")
+ }
+}
+```
diff --git a/contrib_versioned_docs/version-hcaptcha_v0.x.x/hcaptcha/README.md b/contrib_versioned_docs/version-hcaptcha_v0.x.x/hcaptcha/README.md
new file mode 100644
index 00000000000..952956e0168
--- /dev/null
+++ b/contrib_versioned_docs/version-hcaptcha_v0.x.x/hcaptcha/README.md
@@ -0,0 +1,83 @@
+---
+id: hcaptcha
+---
+
+# HCaptcha
+
+![Release](https://img.shields.io/github/v/tag/gofiber/contrib?filter=hcaptcha*)
+[![Discord](https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7)](https://gofiber.io/discord)
+![Test](https://github.com/gofiber/contrib/workflows/Tests/badge.svg)
+![Security](https://github.com/gofiber/contrib/workflows/Security/badge.svg)
+![Linter](https://github.com/gofiber/contrib/workflows/Linter/badge.svg)
+
+A simple [HCaptcha](https://hcaptcha.com) middleware to prevent bot attacks.
+
+:::note
+
+Requires Go **1.21** and above
+
+:::
+
+## Install
+
+:::caution
+
+This middleware only supports Fiber **v3**.
+
+:::
+
+```shell
+go get -u github.com/gofiber/fiber/v3
+go get -u github.com/gofiber/contrib/hcaptcha
+```
+
+## Signature
+
+```go
+hcaptcha.New(config hcaptcha.Config) fiber.Handler
+```
+
+## Config
+
+| Property | Type | Description | Default |
+|:----------------|:----------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------|
+| SecretKey | `string` | The secret key you obtained from the HCaptcha admin panel. This field must not be empty. | `""` |
+| ResponseKeyFunc | `func(fiber.Ctx) (string, error)` | ResponseKeyFunc should return the token that captcha provides upon successful solving. By default, it gets the token from the body by parsing a JSON request and returns the `hcaptcha_token` field. | `hcaptcha.DefaultResponseKeyFunc` |
+| SiteVerifyURL | `string` | This property specifies the API resource used for token authentication. | `https://api.hcaptcha.com/siteverify` |
+
+## Example
+
+```go
+package main
+
+import (
+ "github.com/gofiber/contrib/hcaptcha"
+ "github.com/gofiber/fiber/v3"
+ "log"
+)
+
+const (
+ TestSecretKey = "0x0000000000000000000000000000000000000000"
+ TestSiteKey = "20000000-ffff-ffff-ffff-000000000002"
+)
+
+func main() {
+ app := fiber.New()
+ captcha := hcaptcha.New(hcaptcha.Config{
+ // Must set the secret key
+ SecretKey: TestSecretKey,
+ })
+
+ app.Get("/api/", func(c fiber.Ctx) error {
+ return c.JSON(fiber.Map{
+ "hcaptcha_site_key": TestSiteKey,
+ })
+ })
+
+ app.Post("/api/robots-excluded", func(c fiber.Ctx) error {
+ return c.SendString("You are not a robot")
+ }, captcha)
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
diff --git a/contrib_versioned_docs/version-hcaptcha_v0.x.x/jwt/README.md b/contrib_versioned_docs/version-hcaptcha_v0.x.x/jwt/README.md
new file mode 100644
index 00000000000..49c7e9ed49d
--- /dev/null
+++ b/contrib_versioned_docs/version-hcaptcha_v0.x.x/jwt/README.md
@@ -0,0 +1,300 @@
+---
+id: jwt
+---
+
+# JWT
+
+![Release](https://img.shields.io/github/v/tag/gofiber/contrib?filter=jwt*)
+[![Discord](https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7)](https://gofiber.io/discord)
+![Test](https://github.com/gofiber/contrib/workflows/Tests/badge.svg)
+![Security](https://github.com/gofiber/contrib/workflows/Security/badge.svg)
+![Linter](https://github.com/gofiber/contrib/workflows/Linter/badge.svg)
+
+JWT returns a JSON Web Token (JWT) auth middleware.
+For valid token, it sets the user in Ctx.Locals and calls next handler.
+For invalid token, it returns "401 - Unauthorized" error.
+For missing token, it returns "400 - Bad Request" error.
+
+Special thanks and credits to [Echo](https://echo.labstack.com/middleware/jwt)
+
+**Note: Requires Go 1.19 and above**
+
+## Install
+
+This middleware supports Fiber v1 & v2, install accordingly.
+
+```
+go get -u github.com/gofiber/fiber/v2
+go get -u github.com/gofiber/contrib/jwt
+go get -u github.com/golang-jwt/jwt/v5
+```
+
+## Signature
+```go
+jwtware.New(config ...jwtware.Config) func(*fiber.Ctx) error
+```
+
+## Config
+
+| Property | Type | Description | Default |
+|:---------------|:--------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------|
+| Filter | `func(*fiber.Ctx) bool` | Defines a function to skip middleware | `nil` |
+| SuccessHandler | `func(*fiber.Ctx) error` | SuccessHandler defines a function which is executed for a valid token. | `nil` |
+| ErrorHandler | `func(*fiber.Ctx, error) error` | ErrorHandler defines a function which is executed for an invalid token. | `401 Invalid or expired JWT` |
+| SigningKey | `interface{}` | Signing key to validate token. Used as fallback if SigningKeys has length 0. | `nil` |
+| SigningKeys | `map[string]interface{}` | Map of signing keys to validate token with kid field usage. | `nil` |
+| ContextKey | `string` | Context key to store user information from the token into context. | `"user"` |
+| Claims | `jwt.Claim` | Claims are extendable claims data defining token content. | `jwt.MapClaims{}` |
+| TokenLookup | `string` | TokenLookup is a string in the form of `