Is there a way to detect if a Lightning Component is running in a Community or in Lightning Experience?

You can try to use the SessionManagement Class's getCurrentSession() method, which will return a map of attributes for the users current session. Amongs these, you will find SessionType, which will indicate the context. Here are some that I tested:

Lightning Communities:

  • Preview & BUilder mode: SitePreview
  • Live Site: ChatterNetworks

Ligthning Experience:

  • LEX App page: Aura

further details can be found at Understanding Session Types

You will have to do this in an Apex class and call your method to get the context in your clientside controller.

Since @glls answer is not working, as a workaround we are decomposing the URL. I don't like this approach, but it looks like that Salesforce is leaving us alone on this issue.

We have put the following code inside a js utility-libray we are using via ltng:require in almost all of our components

utility = {
        community : {
            context: (new RegExp('.*?\/s\/','g')).exec(window.location.href) != null,
            is : function() {
                return this.context;
            path : function() {
                let path = (new RegExp(':\/\/(.*\.com)\/([A-Za-z0-9]*\/)?s\/','g')).exec(window.location.href); 
                return this.context != null ? path[2] == undefined ? '' : path[2] : null;
} will be dynamically true in case a hybrid component is running inside Community-context and false if running inside LEX-context.

To do something really useful, we need also the path of the community (can be either blank or a string). You need it e.g. to dynamically compose image-urls, attachment-urls, links, etc. so that a compo is working on ANY community AND in LEX without config or any kind of adjustment.