nerves_hub_link dependency, choose an authentication method, and configure your device to connect to NervesCloud. Once your firmware is flashed, the device will appear online in your NervesHub dashboard automatically.
Configure
NervesHubLink only in config/target.exs (or environment-specific target configs such as config/prod.exs), not in config/config.exs. The link library is a device-side dependency and should never be evaluated on your host machine.1
Add the dependency to mix.exs
Open your project’s Then fetch the new dependency:
mix.exs and add nerves_hub_link to the list of dependencies:2
Add nerves_hub_link to extra_applications
If your If you do not specify
mix.exs specifies an extra_applications list inside the application/0 callback, add :nerves_hub_link so it starts with your application:extra_applications, OTP will start it automatically and you can skip this step.3
Choose an authentication method
NervesHub supports three authentication modes. Pick the one that fits your deployment:
- Device Certificates
- NervesKey
4
Configure config/target.exs
Add the full NervesHubLink configuration block to Using
config/target.exs. The example below uses Shared Secret authentication and targets NervesCloud:System.fetch_env!/1 instead of a literal fallback ensures the build fails fast with a clear error if the environment variable is not set, rather than silently embedding a placeholder in firmware. Set NERVES_HUB_PRODUCT_KEY and NERVES_HUB_PRODUCT_SECRET in your CI/CD system and in your local shell when building firmware.5
Rebuild firmware and verify the connection
Build and burn your firmware with the updated configuration:After the device boots, open the NervesCloud dashboard and navigate to Devices. Your device should appear with a status of Online within a few seconds of connecting to the network.If the device does not appear, check:
- The
product_keyandproduct_secretvalues match exactly what is shown in Products → Settings. - The device has outbound access to
devices.nervescloud.comon port 443. - Your
config/target.exsis being imported correctly (check for a strayimport_configoverride).

