So, to start off, I've seen:

All the answers to those questions make the proposal to make the node unpublished, which was the solution that looked cleanest to me, given that I was making some content types to be viewed exclusively with slideshows, i.e., having www.mysite.com/node/40 showing a list of all the raw images that make up my slideshow in a block elsewhere was not something I wanted. I only want the images viewable within the context of a slideshow.

However, when I followed these answers and made the content of the node unpublished, the content was inaccessible to the slideshow View: It was now blank to anonymous viewers. Is there something I missed in how to make a node unpublished, but still allow its contents to be accessed through Views, as a block?

I'm looking to do this without using the htaccess, hooks, or javascript options I've seen mentioned in the links above.

I can't imagine that having a list of content accessible nakedly under nodes/123 is actually an intentional feature.

One other qualification that makes this a tricky problem---there are ways of preventing access to node/123, but they can also hinder your own ability to create or edit nodes!

  • hello Mittenchops. IMHO, I suggest review again your links, unpublish is not the only answer, there are hooks, views, and other ways listed.
    – cigotete
    Sep 16, 2011 at 21:40
  • Thanks, moon.watcher, I understand, but I think creating the distinction between a private holding area and a public display area seems very useful (and easy). I understand there are other ways, but man, I wish I could get this way to work! Sep 16, 2011 at 21:51
  • Have you tried using htaccess?
    – ram4nd
    Sep 17, 2011 at 11:04
  • Yeah, and I understand that would achieve the right behavior---still, it seems like there should be an in-system way of doing this, right? Some default or checkbox somewhere? Let me modify my question to clarify that part. Thanks! Sep 17, 2011 at 11:06
  • 1
    The accepted answer to drupal.stackexchange.com/questions/5622/… does not require making content unpublished.
    – mpdonadio
    Sep 18, 2011 at 0:10

6 Answers 6


There are two Drupal modules that offer this functionality:

  • Thanks for these! I was going to suggest a custom module to do just this, but of course there's a module for it. The real issue of this question is: how to deal with bits of content that should only be seen in a mashup of some kind, never on its own, and that's exactly what these two modules deal with. More abstractly, any time you've got such content, it's best not to make it a node, but a non-node entity, for this and other reasons (e.g. you probably don't want all those node hooks firing on it).
    – Alan Dixon
    Feb 13, 2015 at 14:19
  • Upvoted for recommending Rabbit Hole. Tried it and does the job easily. Didn't try Internal Nodes so can't compare.
    – consuela
    Jun 5, 2015 at 10:37

Johan Falk of nodeone.se just reciently did an excellent video series on Page Manager (part of cTools, a very common module) and he covered a use case like you are describing very well. link.

Basically you set up a variant in Page Manager and have the response be a http request code (probably a 301 in your case) to redirect to your intended destination. In his example (I think it was the 2nd or 3rd video in the series, they are all pretty quick though) he was using node references and he didn't want anyone to get to a 'sub node' but redirect you to the parent node if you tried to access it. Your use case sounds like it could be even simpler, just have anyone trying to access one of your slideshow nodes redirected to page that shows the correct full slideshow.

You don't even need panels to get all of this magic to work. And you can get pretty complex in your redirect rules if you have stuff like node references installed to load related nodes.

  • Thanks, Chance G! I'm looking through the tutorials now, and maybe that will take care of it. Sep 18, 2011 at 12:59
  • Indeed excellent video series (though not "recently" anymore). And FYI: nodeone.se links don't work anymore. Want to update your link? Aug 10, 2016 at 17:47

If it's just a matter of search engine accessibility you can should use the robot.txt file, which prevent search engines from accessing certain page of your site.

Though using this Technic users of your site can still access URLs like in your example www.mysite.com/node/40

  • Thanks! That makes sense, but is there also a way to make it absolutely inaccessible to non-humans and humans alike? I suppose there's easy .htaccess code for this, but that also seems like overkill. Maybe I'm wrong, but it just seems like the sort of distinction that should be easy and obvious. By this I mean: I can't imagine anyone would intentionally want a list of poorly formatted junk under a node menu, you know? Sep 16, 2011 at 21:53
  • Yes then i ll save your question for later as i wonder myself wonder how to achieve that as well. I haven't got time to investigate this just yet, but if i get an answer anytime soon, i ll make sure to post it here. Though as moon.watcher suggested you should edit your question title it's a little confusing.
    – silkAdmin
    Sep 16, 2011 at 22:01
  • OK, cool, I've adjusted the title to clarify the "completely" instead of the "search engine" focus. Thanks! Sep 17, 2011 at 9:28


I discovered that any access rules I could add to enable the administrator to create and edit content, because editing content is under "/node/add/..." also undid the anonymous user access restriction and enabled all users to see the content. Sort of back where I started, but leaving this up in case it helps anyone else see the way. Original answer follows:

OK, here's the recipe to achieve this in a non-programmatic way, as simply as I could (explanation of why follows):

  1. Enable the Page Manager module (part of ctools), install and enable the Page Manager Redirect module: http://drupal.org/project/page_manager_redirect.
  2. In the admin menu, go to Structure >> Pages
  3. In the table below, identify the custom page "System node_view Node template /node/%node " and click "edit" on the right.
  4. For me, I had by default "Basic Page" and "Storyauthors." I hit disable on both of these (but you may want to preserve them, if you use these features---I do not).
  5. Click "Add Variant"
  6. Title: "redirect to main." Variant type: "HTTP Response Code." And Check "Selection Rules." Click "Create Variant."
  7. Now, add selection rules.
    7.a. In the drop-down box, go to "user: Role," click "Add." >> NOT (Logged in user has role "administrator")
    7.b. Add another selection rule >> node:type. Click every content type for which you do not want a user to be able to see naked nodes. Then click NOT. For me, since I never want naked nodes to be visible, I clicked every content type I have.
  8. Set HTTP response code to 301, and leave the redirect blank (= to main).

The rationale:

  • I went this route instead of htaccess or creating modules because this seems like the sort of problem that should be accessibly fixable within the interface. Again, I don't believe there would be a group clamoring for all content to be visible under nodes/, numbered, if it weren't the default behavior.
  • Regarding selection rules: The first one, for administrator (or any editor-level group you have), ensures that you can still create and edit content! If you leave this off, when you try to add new content, you will be redirected to main. The second one, about content types, was necessary to allow viewing pages under their URL alias. Without this checked, when I clicked on say, blog posts, I was unable to view them at full page, only their teasers. Not sure why this was the case, or why I needed to do negative permissions here, rather than positive permissions. But this is what I had to change to allow editors to edit, and anonymous viewers to view formatted content types and not node/.

Potential pitfalls:

If you create a new content type, you'll need to remember to come back to page manager and update (ie, check its box in the second selection rule).

Future improvement:

If someone is really cool, they'd make a single module that does this process automatically, and call it "Hide nodes." =) Again, I wish hiding "nodes/" were default Drupal behavior, and I'm sure I'm not the only one. I really view these as a staging and collection area---it seems very strange to allow them to be visible to the public. It's like seeing the magician shove the pigeons in his sleeves!

Thanks to Chance G's pointing me there, and Johan Falk's tutorial for getting me going!


From the above, I'm going to say the answer to this question is there's no way to do this. You're stuck with nodes!

  • Honing in a little more, it seems that the problem is that I want "basic page" to always be visible to allow, say, individual blog posts to be visible, but unfortunately, seeing node/123 on its own is also a basic page. However, maybe this points the way to another solution? How can I get node/123 to not count as a basic page, but blog/my-blog-post to count? Sep 18, 2011 at 15:04
  • Hey would you mind accepting another answer instead?
    – leymannx
    Aug 11, 2017 at 20:35

As no one has given a code answer here is another option:

 * Implements hook_init().
function HOOK_init() {
  $object = menu_get_object();
  $action = arg(2);
  if(isset($object->type) && $object->type == 'TYPE_OF_NODE' && (empty($action) || $action == 'view')) {

Replace HOOK with the name of your module and replace TYPE_OF_NODE with the name of the type of node that you want to hide.

This will only redirect when the path is node/123 or node/123/view. node/123/edit or node/123/whatever is allowed. Note this is the path, not the URL I'm talking about. The path alias of the node is irrelevant here.


Using the Rules module you can implement a rule that looks similar to this:

{ "rules_check_url" : {
    "LABEL" : "Disallow node/* access",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "text_matches" : {
          "text" : [ "site:current-page:url" ],
          "match" : "node\/\\d+$",
          "operation" : "regex"
    "DO" : [
      { "drupal_message" : {
          "message" : "Sorry, URLs like [site:current-page:url] are not allowed around here ...",
          "type" : "error"
      { "redirect" : { "url" : "no_access" } }

Anybody using an URL like node/... will be redirected to a page with path no_access (adapt that path to fit your needs).

The above rule does not (yet) take into account to only apply the "action" for selected roles (such as anonymous users) only. But for anybody a bit familiar with the Rules module, that is a straight forward "Condition" to add ... Should you only want to prevent such access to a limited list (a few) of nodes, then there is no need to use the "regex" operation in the "text_matches" condition (just replace it with an exact match of the relevant node(s)).

To experiment with this rule in your own site, just copy the entire Rules code above, and paste it in a new Rule in your own site, created via the "Import" function. Then further edit/refine to make it fit in your own environment (e.g the "Sorry, ..." message to be shown).

Attention: this rule takes the "completely"-part from the question title seriously ... With this rule enabled (with no extra Rules condition added to only apply it for selected rules), even an administrator (or user/1 ...) will not be able to get access to any (repeat: any) URL like node/.... The only way to get around that, is to (temporary) disable this rule, add relevant Rules conditions (to allow selected roles anyway), and enable the rule again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.