Problem/Motivation

When publishing a new node without any previous revisions. Because index_now is before pathauto alphabetically, the index_now's entity_insert hook is triggered before the pathauto one, resulting in the generated URL being sent to Index Now being the unaliased URL /node/123.

Steps to reproduce

1. Create a new Node with pathauto enabled on it.
2. Publish it directly so that pathauto generates an alias for it.
3. The initial URL sent to Index Now will be the unaliased node URL rather than the path alias.

Proposed resolution

Increase the module weight so that its hooks are triggered after most modules by default (or at least pathauto's)

Remaining tasks

Provide MR.

User interface changes

N/A

API changes

Index Now hooks will be ran after most module hooks.

Data model changes

N/A

Issue fork index_now-3607002

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

codebymikey created an issue. See original summary.

codebymikey’s picture

Status: Active » Needs review

Create an update hook that explicitly sets the module weight to 10 by default, allowing all the relevant hooks to be ran after pathauto and most other modules.

The alternative is to implement an hook_module_implements_alter() hook, but I think an explicit weight is more obvious here, and sites needing a higher weight on the module can always manually increase it to fit their use case.

For those needing a patch on 3.1.x, I'd use this version of the patch for now until an agreement has been made to go forward with it, otherwise you might not longer be able to easily apply the 10003 database update if it's used for something else.

macsim’s picture

Status: Needs review » Needs work

Hi codebymikey,

Thanks for the report. After reviewing the code more carefully, I want to clarify the actual behavior.

The module implements both hook_entity_insert and hook_path_alias_insert.
When a new node is created with a Pathauto pattern, the sequence is:

  1. hook_entity_insert → Index Now fires before Pathauto (alphabetical order, same weight) → no alias yet → pings /node/123
  2. hook_entity_insert → Pathauto fires → generates and saves the alias
  3. hook_path_alias_insert → Index Now fires → pings /my-alias

So the aliased URL is correctly submitted via hook_path_alias_insert. The issue is not that the alias URL is never sent — it's that an extra, unnecessary ping is sent first with the system path.

There is already an in-memory deduplication system ($sentUrls) that prevents double pings when both hooks resolve to the same URL (which works correctly for updates). But on insert, the two pings resolve to different URLs, so deduplication does not help.

Regarding the proposed fix (setting module weight to 10): while functional, this approach is fragile — it relies on Pathauto keeping its default weight of 0, which is not guaranteed.

A more robust solution would be to defer all pings collected during hook_entity_insert to a KernelEvents::TERMINATE subscriber. By that point, all entity hooks have run, path aliases are available, and the correct canonical URL can be resolved. The existing $sentUrls deduplication would then also handle the subsequent hook_path_alias_insert ping naturally.

This would be a more significant refactor, but it would solve both the ordering issue and the double-ping issue in a way that does not depend on module weights.

codebymikey’s picture

This would be a more significant refactor, but it would solve both the ordering issue and the double-ping issue in a way that does not depend on module weights.

Yeah, that seems like a lot more intuitive way to address the issue. I just picked the quickest way of addressing the current issue without changing how the indexing mechanism currently works.

macsim’s picture

Assigned: Unassigned » macsim
macsim’s picture

While implementing this fix, I also noticed that hook_entity_delete pings never resolve to the aliased URL:
PathFieldItemList::delete() removes path aliases from the database inside doDelete(), before hook_entity_delete fires. This means Url::fromRoute() always resolves to the system path (/node/123) when an entity is deleted.

This would deserve its own dedicated issue, but since we are already introducing the KernelEvents::TERMINATE deferral system, it makes sense to handle it at the same time by capturing the canonical URL in hook_entity_predelete — before doDelete() runs — and deferring the ping alongside insert and update events.

I am extending the scope of this issue to include this fix.

macsim’s picture

Manually tested the fix with Pathauto enabled:

  • Node creation: IndexNow receives the aliased URL, not /node/{id}
  • Node update: the alias is correctly resolved at request termination; when the path alias changes, both the old and the new alias are pinged
  • Node deletion: the aliased URL is captured in hook_entity_predelete before Pathauto removes it, and sent on KernelEvents::TERMINATE

All three cases work as expected. The unit tests also cover the deferral logic and the predelete URL capture.

For me it's RTBC for 4.0.x
Going to port it on 3.1.x

macsim’s picture

Status: Needs work » Needs review

Seems to also be ok on 3.1.x

macsim’s picture

Note: Tests failures on 4.0.x MR are because I bumped the core minimal requirement to drupal 11.4 for 4.0.x while the CI still runs on 11.3

Drupal installed version: 11.3.12
....
Drupal\Core\Extension\MissingDependencyException: Unable to install modules: module 'index_now_node' is incompatible with this version of Drupal core.
macsim’s picture

Status: Needs review » Reviewed & tested by the community

  • macsim committed 89985d45 on 3.1.x authored by codebymikey
    task: #3607002 Ensure that the index_now hooks are run after pathauto
    

  • macsim committed 0402c8ff on 4.0.x authored by codebymikey
    task: #3607002 Ensure that the index_now hooks are run after pathauto
    
macsim’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

codebymikey’s picture

Apologies for the lack of updates here, but thanks for getting this over the line!

From some cursory tests, everything seems to be working brilliantly.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.