Textpattern CMS support forum
You are not logged in. Register | Login | Help
- Topics: Active | Unanswered
Pages: 1
Trailing slashes with nginx
Hi everyone, long time lurker, first time poster :).
My test Textpattern 4.9.1 site uses nginx and php-fpm on FreeBSD. The config is barebones for now:
upstream php {
server unix:/var/run/php-fpm.sock;
}
server {
listen 80;
server_name test.server.lan;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$is_args$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass php;
}
}
When I have Article URL Pattern set to /title, all these work great:
//pages//index.php?id=2/example-article-bloke-is-a-champ(article with ID 2)
But when I change Add a trailing slash to URLs from List to Yes, Textpattern now returns 404s for these:
/example-article-bloke-is-a-champ/example-article-bloke-is-a-champ/
Any fellow nginx tragics have persistent trailing slashes for URLs working with trailing slashes set to Yes?
Offline
Re: Trailing slashes with nginx
The plot thickens: I changed Article URL pattern from /title to /id/title to test, and this now works!
/example-article-bloke-is-a-champ/
So it seems nginx and/or Textpattern can’t handle the combination of Add a trailing slash to URLs being set to Yes, and and the Article URL pattern being set to just /title. Will keep digging.
Offline
Re: Trailing slashes with nginx
Hmmm, that is intriguing. I wonder if we’ve missed an edge case in the URL parser, or if this is specific to nginx (or both?).
I don’t have an nginx environment set up locally but the demo server does, so there’s a potential testbed there.
Anything further you could uncover would be amazing. Thank you for bringing this up.
The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.
Hire Txp Builders – finely-crafted code, design and Txp
Offline
Re: Trailing slashes with nginx
Thanks Bloke :). I was able to reproduce in the current release demo for 4.9.1.
Steps:
- Log into the admin UI
- Go to Admin > Preferences > Site
- Set Article URL pattern to /title
- Set Add a trailing slash to URLs from List to Yes
The default theme correctly links to the appropriate URL, so that’s all good! But the default welcome article is then inaccessible at either of these URLs:
- https://release-demo.textpattern.co/welcome-to-textpattern
- https://release-demo.textpattern.co/welcome-to-textpattern/
According to the Diagnostics tab, the server is also running nginx (as you pointed out). But that might be a red herring here. I’ll try spinning up an Apache server and see if I can reproduce there.
(For a bit of background, I’m looking into migrating a few long-running WordPress sites I host for people over to Textpattern, which I’d far prefer to administer! They were all configured with just the /title/ for their permalinks, so I’d need to be able to preserve these if at all possible).
Last edited by rubenerd (2026-05-27 03:00:47)
Offline
Re: Trailing slashes with nginx
Hi @rubenerd, welcome to the forum and thanks for the report.
Bloke wrote #343292:
Hmmm, that is intriguing. I wonder if we’ve missed an edge case in the URL parser, or if this is specific to nginx (or both?).
It seems to work fine on my local apache, which complicates debugging, since
I don’t have an nginx environment set up locally …
and me neither. Will try to play with the demo server, but it looks cumbersome.
Offline
Re: Trailing slashes with nginx
Thanks @etc. Such a breath of fresh air using TXP again after dealing with WP, even in spite of this random issue.
I’ve built a fresh VM with a more traditional LAMP stack (Debian Apache2 MySQL php) and Textpattern 4.9.1, but I’m getting the same issue. As soon as I set those two config options, article links (1) with a trailing slash or (B) without return 404.
I’m wondering if it’s PEBKAC during config? I didn’t think I was doing anything exotic. Pre-flight checks are all fine, and nothing from the Diagnostics page jumps out at me. Feel free to point out if I’m doing something silly (it wouldn’t be the first time).
In the meantime I’ll keep digging.
Textpattern version: 4.9.1 (84a30a58a5375ba307e2053d0b2c6dcd263eae46850f1e1f)
Last update: 2026-02-14 17:01:39
Site URL: textpatterntest.rubenerd.au
Admin URL: textpatterntest.rubenerd.au/textpattern
Document root: /var/www/textpattern
$path_to_site: /var/www/textpattern
Textpattern path: /var/www/textpattern/textpattern
Article URL pattern: title_only
Production status: testing
Temporary directory path: /tmp
PHP version: 8.4.21
GD Graphics Library: 2.3.3; Supported formats: GIF, JPEG, PNG, WebP, AVIF.
Server time zone: UTC
Server local time: 2026-05-28 03:39:58
Daylight Saving Time enabled?: 0
Automatically adjust Daylight Saving Time setting?: 0
Time zone (GMT offset in seconds): UTC (+0)
MySQL: 11.8.6-MariaDB-0+deb13u1 from Debian (-- Please help get to 10k stars at https://github.com/MariaDB/Server)
Database server time: 2026-05-28 03:39:58
Database server time offset: -1 s
Database server time zone: SYSTEM
Database session time zone: SYSTEM
Locale: en_US.UTF-8
Site / Admin language: en / en
Web server: Apache/2.4.67 (Debian)
Apache version: Apache/2.4.67 (Debian)
PHP server API: apache2handler
PHP SSL version: OpenSSL 3.5.5 27 Jan 2026
RFC 2616 headers:
Server OS: Linux 6.12.48+deb13-amd64
Admin-side theme: hive 4.9.1
.htaccess file contents:
------------------------
# BEGIN Textpattern
#DirectoryIndex index.php index.html
<IfModule mod_rewrite.c>
RewriteEngine On
#Options +FollowSymlinks
#RewriteBase /relative/web/path/
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+) - [PT,L]
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*) index.php
RewriteCond %{HTTP:Authorization} !^$
RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}]
</IfModule>
<IfModule mod_mime.c>
AddType image/svg+xml svg svgz
AddEncoding gzip svgz
</IfModule>
# For .htaccess configuration settings and explanations, please refer to:
# https://github.com/h5bp/server-configs-apache/blob/main/dist/.htaccess
# https://httpd.apache.org/docs/
# END Textpattern
------------------------
Offline
Re: Trailing slashes with nginx
any clues from this post, specifically the answer provided?
server {
listen 80;
server_name example.com;
# This WORKS!
root /var/www/example/public;
…. texted postive
Offline
Re: Trailing slashes with nginx
Ok, thank you, I can reproduce the issue. It happens (whatever server) when only one (default) url pattern is used site-wise. URL resolution logic is simplified in this case, but probably too much. Will fix in 4.9.2. Meanwhile, if you create an empty section and assign it a different (from default) url scheme, it should work. Sorry for the hassle.
Offline
Re: Trailing slashes with nginx
Thanks @etc! You’ve made my day :).
etc: Meanwhile, if you create an empty section and assign it a different (from default) url scheme, it should work.
Can confirm this works on every server I’ve tried.
bici: any clues from this post, specifically the answer provided?
Thanks @bici, that was the last bit I needed to make sure URLs are rewritten with forward slashes correctly. I’ve been using nginx as my default for at least the last decade, and its syntax still throws me sometimes.
Offline
Pages: 1