# Feature Toggles

Lighthouse allows you to conditionally show or hide elements (fields, types, arguments or input fields) of your schema.

# @show and @hide

The directives @show and @hide work in a similar way, but are logical opposites of each other.

For example, you might want to limit an experimental new field to test environments. @show is most suitable for this:

type Query {
  testInformation: String! @show(env: ["integration", "staging"])
}

Another example would be a field that should be available in every environment but production. In this case, @hide fits better:

type Query {
  debugInformation: String! @hide(env: ["production"])
}

# @feature

The @feature directive allows to include fields, types, arguments, or input fields in the schema depending on whether a Laravel Pennant (opens new window) feature is active.

For example, you might want a new experimental field only to be available when the according feature is active:

type Query {
  experimentalField: String! @feature(name: "new-api")
}

In this case, experimentalField will only be included when the new-api feature is active.

Another example would be to only include a field when the feature is inactive:

type Query {
  deprecatedField: String! @feature(name: "new-api", when: "INACTIVE")
}

When using class based features (opens new window), the fully qualified class name must be used as the value for the name argument:

type Query {
  experimentalField: String! @feature(name: "App\\Features\\NewApi")
}

# Conditional Type Inclusion

When you conditionally include a type using @show, @hide or @feature, any fields using it must also be conditionally included. If the type is omitted but still used somewhere, the schema will be invalid.

type ExperimentalType @feature(name: "new-api") {
  field: String!
}

type Query {
  experimentalField: ExperimentalType @feature(name: "new-api")
}

# Interaction With Schema Cache

@show and @hide work by manipulating the schema. This means that when using their env option, the inclusion or exclusion of elements depends on the value of app()->environment() at the time the schema is built and not update on later environment changes. If you are pre-generating your schema cache, make sure to match the environment to your deployment target.

The same goes for @feature. Whether a field is included in the schema will be based on the state of a feature at the time the schema is built. In addition, if you are pre-generating your schema cache, you will only be able to use features that support nullable scopes (opens new window), as there won't be an authenticated user to check the feature against.