Skip to content

Instantly share code, notes, and snippets.

@gregblake
Last active January 5, 2026 22:15
Show Gist options
  • Select an option

  • Save gregblake/94ee62712abc80df4da4ff104c40cca7 to your computer and use it in GitHub Desktop.

Select an option

Save gregblake/94ee62712abc80df4da4ff104c40cca7 to your computer and use it in GitHub Desktop.
Nitro-Web: Relative URL Issues in NotificationCenter and ConnectClient

Nitro-Web: Relative URL Issues in NotificationCenter and ConnectClient

Summary of this gist: after Michelle and I chatted about https://runway.powerhrg.com/backlog_items/FINC-3481?from=active_sprint, I asked a chat bot to summarize other places in nitro-web that might have the same behavior.

Problem

Many notifiers throughout the codebase are using relative paths (_path helpers or hardcoded paths) instead of fully qualified URLs when sending notifications via NotificationCenter.notify() or ConnectClient.message_user(). This causes issues when the notifications are sent through Connect messages, as the links don't include the domain.

Files Using Relative Paths (Problematic)

Human Resources

Travel

Attendance

Leave

Time Off Transition

Recruiting

Surveys

Compensation

Files Using Fully Qualified URLs (Correct) ✓

Correct Patterns

Pattern 1: Using NitroConfig base URL

def url_slug
  base_url = NitroConfig.get!("nitro/base_url")
  "#{base_url}/user_requests/#{id}"
end

Pattern 2: Using Rails URL helpers with _url suffix

def notification_url
  Reimbursements::Engine.routes.url_helpers.manager_show_request_url(request)
end
@gregblake
Copy link
Author

gregblake commented Jan 5, 2026

Since this is happening in multiple places throughout nitro-web and we are dealing with existing url records that are only validated as strings, I think the right solution is to normalize the url within the notification model:

Something like this:

before_validation :normalize_url

private

def normalize_url
  return if url.blank?
  return if url.start_with?("http://", "https://")

  base_url = NitroConfig.get!("nitro/base_url")
  self.url = "#{base_url.chomp('/')}#{url.start_with?('/') ? url : "/#{url}"}"
end

I haven't tested the above (and there might be edge cases I'm missing here) but I think that would account for the majority of scenarios.

Alternatively we can update the callers to use fully qualified domains.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment